国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

STM32MP157驅動開發(fā)——LED驅動(原始架構)

這篇具有很好參考價值的文章主要介紹了STM32MP157驅動開發(fā)——LED驅動(原始架構)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

硬件知識 LED 原理

LED 的驅動方式,常見的有四種。

  • ① 使用引腳輸出 3.3V 點亮 LED,輸出 0V 熄滅 LED。
  • ② 使用引腳拉低到 0V 點亮 LED,輸出 3.3V 熄滅 LED。
  • ③ 使用引腳輸出 1.2V 點亮 LED,輸出 0V 熄滅 LED。
  • ④ 使用引腳輸出 0V 點亮 LED,輸出 1.2V 熄滅 LED。

有的芯片為了省電等原因,其引腳驅動能力不足,這時可以使用三極管驅動(如方式3和4)。
stm32mp157,架構,stm32,單片機
由此,主芯片引腳輸出高電平/低電平,即可改變 LED 狀態(tài),而無需關注GPIO 引腳輸出的是 3.3V 還是 1.2V。所以簡稱輸出 1 或 0:

GPIO 引腳操作方法

GPIO 模塊一般結構

  • 有多組 GPIO,每組有多個 GPIO
  • 使能:電源/時鐘
  • 模式(Mode):引腳可用于 GPIO 或串口或其他功能
  • 方向:引腳 Mode 設置為 GPIO 時,可以繼續(xù)設置它是輸出引腳,還是輸入引腳
  • 數(shù)值
    • 對于輸出引腳,可以設置寄存器讓它輸出高、低電平
    • 對于輸入引腳,可以讀取寄存器得到引腳的當前電平

GPIO 寄存器的一般操作

芯片手冊一般有相關章節(jié),用來介紹:power/clock

  • 可以設置對應寄存器使能某個 GPIO 模塊(Module)
  • 有些芯片的 GPIO 是沒有使能開關的,即它總是使能的

一個引腳可以用于 GPIO、串口、USB 或其他功能,

  • 有對應的寄存器來選擇引腳的功能

對于已經設置為 GPIO 功能的引腳,有方向寄存器用來設置它的方向:輸出、輸入

對于已經設置為 GPIO 功能的引腳,有數(shù)據寄存器用來寫、讀引腳電平狀態(tài);GPIO 寄存器的 2 種操作方法:

  • 直接讀寫:讀出、修改對應位、寫入
a) 要設置 bit n:
val = data_reg;
val = val | (1<<n);
data_reg = val;

b) 要清除 bit n:
val = data_reg;
val = val & ~(1<<n);
data_reg = val;
  • set-and-clear protocol:
set_reg, clr_reg, data_reg 三個寄存器對應的是同一個物理寄存器,
a) 要設置 bit n:set_reg = (1<<n);
b) 要清除 bit n:clr_reg = (1<<n);//這里的置1表示該位清零,硬件內部會操作

STM32MP157的GPIO操作方法

先使能PLL4

PLL4用于給各種外設提供時鐘,最先要使能PLL4;

GPIO是低速設備,我們可以先不去設置PLL4的頻率;僅僅使能即可

GPIO 外設的時鐘來源各自不同,具體的可以從手冊當中可以看到,其中 GPIOA-K 的時鐘來源為 hclk4,GPIOZ 的時鐘來源為 hclk5。因此為了使用 GPIO,我們需要使能鎖相環(huán)和外設 GPIO 各自對應的時鐘。設置 RCC_PLL4CR 使能 hclk4 使用的時鐘

RCC_PLL4CR地址:0x50000000 + 0x894

stm32mp157,架構,stm32,單片機
還需要讀取bit 1 ,查看PLL4是否使能

MPU、MCU共享GPIO模塊

對于A7、M4而言,GPIO模塊是公用的,寄存器的操作也是類似的
stm32mp157,架構,stm32,單片機

1. 在MPU上使能某個GPIO模塊

stm32mp157,架構,stm32,單片機

2. 在MCU上使能某個GPIO模塊

stm32mp157,架構,stm32,單片機

GPIO模塊

GPIO引腳電路原理圖:
stm32mp157,架構,stm32,單片機
對于 STM32MP157 來說,每一個 GPIO 端口有四個 32 位的配置寄存器(GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR 和 GPIOx_PUPDR),兩個32 位的數(shù)據寄存器(GPIOx_IDR 和 GPIOx_ODR),一個 32 位的設置/復位寄存器(GPIOx_BSRR)。此外,所有的 GPIO 都有一個 32 位的鎖定寄存器(GPIOx_LCKR)和兩個 32 位的多功能選擇寄存器(GPIOx_AFRH andGPIOx_AFRL)。此外,還有 GPIO 外設時鐘控制寄存器。

設置引腳工作模式:GPIO模式

stm32mp157,架構,stm32,單片機

對于輸出引腳:設置輸出類型

stm32mp157,架構,stm32,單片機

對于輸出引腳:設置輸出速度

stm32mp157,架構,stm32,單片機
輸出速度越快越容易對其他外設造成影響

對于輸入/輸出引腳:設置上下拉電阻

stm32mp157,架構,stm32,單片機

對于輸入/輸出引腳:讀取引腳電平

stm32mp157,架構,stm32,單片機

對于輸出引腳:設置引腳電平,方法1

stm32mp157,架構,stm32,單片機

對于輸出引腳:設置引腳電平,方法2

該方法部分芯片支持,需要閱讀芯片手冊
stm32mp157,架構,stm32,單片機

STM32MP157的LED操作方法

LED的操作主要分為兩個部分:

  1. 查看開發(fā)板內部的LED原理圖(引腳),GPIOA的基地址
  2. 查看開發(fā)板GPIO的操作方法

所以,打開原理圖,該開發(fā)板提供兩個LED模塊
stm32mp157,架構,stm32,單片機
本次實驗使用到的 GPIOA 和 GPIOG 的基地址
stm32mp157,架構,stm32,單片機

根據上一章中GPIO操作的方法,操作指定寄存器,完成指定功能

  1. 先使能PLL4:RCC_PLL4CR地址:0x50000000 + 0x894
  2. 使能GPIOA:RCC_MP_AHB4ENSETR地址:0x50000000 + 0xA28(或RCC_MC_AHB4ENSETR地址:0x50000000 + 0xAA8)
  3. 設置PA10,用作輸出:GPIOA_MODER地址:0x50002000 + 0x00,設置bit[21:20]=0b01
  4. 設置PA10的輸出電平:
    1. 方法一:讀寄存、修改值、寫回去(低效):GPIOA_ODR地址: 0x50002000 + 0x14
    2. 方法二:直接寫寄存器,一次操作即可,高效GPIOA_BSRR地址: 0x50002000 + 0x18

STM32MP157點亮LED燈

功能:

  • 實現(xiàn) led_open 函數(shù),在里面初始化 LED 引腳。
  • 實現(xiàn) led_write 函數(shù),在里面根據 APP 傳來的值控制 LED。

led_drv.c

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/mutex.h>
#include <linux/wait.h>
#include <linux/uaccess.h>
#include <asm/io.h>
#include <linux/device.h>

static int major;
static struct class *led_class;

/* registers */
// RCC_PLL4CR地址:0x50000000 + 0x894
static volatile unsigned int *RCC_PLL4CR = NULL;

// RCC_MP_AHB4ENSETR 地址:0x50000000 + 0xA28
static volatile unsigned int *RCC_MP_AHB4ENSETR = NULL;

// GPIOA_MODER 地址:0x50002000 + 0x00
static volatile unsigned int *GPIOA_MODER = NULL;

// GPIOA_BSRR 地址: 0x50002000 + 0x18
static volatile unsigned int *GPIOA_BSRR = NULL;

static ssize_t led_write(struct file *filp, const char __user *buf,
			 size_t count, loff_t *ppos)
{
	char val;
	/* copy_from_user : get data from app */
	copy_from_user(&val, buf, 1);

	/* to set gpio register: out 1/0 */
	if (val)
	{
		/* set gpa10 to let led on */
		*GPIOA_BSRR = (1<<26);
	}
	else
	{

		/* set gpa10 to let led off */
		*GPIOA_BSRR = (1<<10);
	}
	return 1;
}

static int led_open(struct inode *inode, struct file *filp)
{
	/* enalbe PLL4, it is clock source for all gpio */
	*RCC_PLL4CR |= (1<<0);
	while ((*RCC_PLL4CR & (1<<1)) == 0);
	
	/* enable gpioA */
	*RCC_MP_AHB4ENSETR |= (1<<0);
	
	/*
	 * configure gpa10 as gpio
	 * configure gpio as output 
	 */
	*GPIOA_MODER &= ~(3<<20);//清零
	*GPIOA_MODER |= (1<<20);

	return 0;
}

static struct file_operations led_fops = {
	.owner		= THIS_MODULE,
	.write		= led_write,
	.open		= led_open,
};

/* 入口函數(shù) */
static int __init led_init(void)
{
	printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
	
	major = register_chrdev(0, "my_led", &led_fops);

	/* ioremap(base_phy, size); */
	// RCC_PLL4CR地址:0x50000000 + 0x894
	RCC_PLL4CR =  (volatile unsigned int *)ioremap(0x50000000 + 0x894, 4);
	
	// RCC_MP_AHB4ENSETR 地址:0x50000000 + 0xA28
	RCC_MP_AHB4ENSETR =  (volatile unsigned int *)ioremap(0x50000000 + 0xA28, 4);
	
	// GPIOA_MODER 地址:0x50002000 + 0x00
	GPIOA_MODER =  (volatile unsigned int *)ioremap(0x50002000 + 0x00, 4);
	
	// GPIOA_BSRR 地址: 0x50002000 + 0x18
	GPIOA_BSRR =  (volatile unsigned int *)ioremap(0x50002000 + 0x18, 4);

	led_class = class_create(THIS_MODULE, "myled");
	device_create(led_class, NULL, MKDEV(major, 0), NULL, "myled"); /* /dev/myled */
	
	return 0;
}

static void __exit led_exit(void)
{
	iounmap(RCC_PLL4CR);
	iounmap(RCC_MP_AHB4ENSETR);
	iounmap(GPIOA_MODER);
	iounmap(GPIOA_BSRR);
	
	device_destroy(led_class, MKDEV(major, 0));
	class_destroy(led_class);
	
	unregister_chrdev(major, "my_led");
}

module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");

ledtest.c

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>


// ledtest /dev/myled on
// ledtest /dev/myled off

int main(int argc, char **argv)
{
	int fd;
	char status = 0;
	
	if (argc != 3)
	{
		printf("Usage: %s <dev> <on|off>\n", argv[0]);
		printf("  eg: %s /dev/myled on\n", argv[0]);
		printf("  eg: %s /dev/myled off\n", argv[0]);
		return -1;
	}
	// open
	fd = open(argv[1], O_RDWR);
	if (fd < 0)
	{
		printf("can not open %s\n", argv[0]);
		return -1;
	}

	// write
	if (strcmp(argv[2], "on") == 0)
	{
		status = 1;
	}

	write(fd, &status, 1);
	return 0;	
}

Makefile

# 1. 使用不同的開發(fā)板內核時, 一定要修改KERN_DIR
# 2. KERN_DIR中的內核要事先配置、編譯, 為了能編譯內核, 要先設置下列環(huán)境變量:
# 2.1 ARCH,          比如: export ARCH=arm64
# 2.2 CROSS_COMPILE, 比如: export CROSS_COMPILE=aarch64-linux-gnu-
# 2.3 PATH,          比如: export PATH=$PATH:/home/book/100ask_stm32mp157_pro-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin 
# 注意: 不同的開發(fā)板不同的編譯器上述3個環(huán)境變量不一定相同,
#       請參考各開發(fā)板的高級用戶使用手冊

KERN_DIR = /home/book/100ask_stm32mp157_pro-sdk/Linux-5.4

all:
	make -C $(KERN_DIR) M=`pwd` modules 
	$(CROSS_COMPILE)gcc -o ledtest ledtest.c 

clean:
	make -C $(KERN_DIR) M=`pwd` modules clean
	rm -rf modules.order
	rm -f ledtest

obj-m	+= led_drv.o

makefile原理可以查看博文:驅動程序——字符設備驅動框架

編譯測試

在Makefile文件目錄下執(zhí)行make指令,此時,目錄下有編譯好的內核模塊hello_drv.ko和可執(zhí)行程序hello_drv_test,移植到開發(fā)板上文章來源地址http://www.zghlxwxcb.cn/news/detail-772876.html

insmod /mnt/led_drv.ko //掛載驅動程序
echo none > /sys/class/leds/heartbeat/trigger // 關閉心跳燈
./ledtest /dev/myled on // 點燈
./ledtest /dev/myled off 

到了這里,關于STM32MP157驅動開發(fā)——LED驅動(原始架構)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • STM32MP157驅動開發(fā)——按鍵驅動(工作隊列)

    STM32MP157驅動開發(fā)——按鍵驅動(工作隊列)

    定時器、下半部 tasklet,它們都是在中斷上下文中執(zhí)行,它們無法休眠。當要處理更復雜的事情時,往往更耗時。這些更耗時的工作放在定時器或是下半部中,會使得系統(tǒng)很卡;并且循環(huán)等待某件事情完成也太浪費CPU 資源了。如果使用線程來處理這些耗時的工作,那就可以解

    2024年02月15日
    瀏覽(25)
  • STM32MP157驅動開發(fā)——按鍵驅動(tasklet)

    STM32MP157驅動開發(fā)——按鍵驅動(tasklet)

    閱讀Linux 系統(tǒng)中異常與中斷可知,Linux 系統(tǒng)對中斷處理的演進過程中,實現(xiàn)了中斷的擴展:硬件中斷、軟件中斷 硬件中斷有:GPIO,網絡中斷(net),系統(tǒng)滴答中斷(tick)等 軟件中斷有:定時器,tasklet等 內核中的軟中斷: 該數(shù)組里面有個action成員,該成員是個函數(shù),函數(shù)會調

    2024年02月14日
    瀏覽(80)
  • STM32MP157驅動開發(fā)——按鍵驅動(POLL 機制)

    STM32MP157驅動開發(fā)——按鍵驅動(POLL 機制)

    使用休眠-喚醒的方式等待某個事件發(fā)生時,有一個缺點:等待的時間可能很久。我們可以加上一個超時時間,這時就可以使用 poll 機制。 ① APP 不知道驅動程序中是否有數(shù)據,可以先調用 poll 函數(shù)查詢一下,poll 函數(shù)可以傳入超時時間; ② APP 進入內核態(tài), 調用到驅動程序的

    2024年02月15日
    瀏覽(19)
  • STM32MP157驅動開發(fā)——按鍵驅動(定時器)

    STM32MP157驅動開發(fā)——按鍵驅動(定時器)

    定時器涉及函數(shù)參考內核源碼:includelinuxtimer.h 給定時器的各個參數(shù)賦值: 設置定時器 :主要是初始化 timer_list 結構體,設置其中的函數(shù)、參數(shù)。 a) 向內核添加定時器。timer-expires 表示超時時間。 b) 當超時時間到達,內核就會調用這個函數(shù):timer-function(timer-data)。 修改定時

    2024年02月15日
    瀏覽(23)
  • STM32MP157驅動開發(fā)——按鍵驅動(線程化處理)

    STM32MP157驅動開發(fā)——按鍵驅動(線程化處理)

    工作隊列是在內核的線程的上下文中執(zhí)行的 工作隊列中有多個 work,前一個 work 沒處理完會影響后面的 work。解決方法有如下2種: 比如自己創(chuàng)建一個內核線程,不跟別的 work 在一塊。例如存儲設備比如 SD/TF采用的就是單獨一個線程。 使用線程化的中斷處理。中斷的處理仍然

    2024年02月16日
    瀏覽(23)
  • STM32MP157驅動開發(fā)——按鍵驅動(休眠與喚醒)

    STM32MP157驅動開發(fā)——按鍵驅動(休眠與喚醒)

    當應用程序必須等待某個事件發(fā)生,比如必須等待按鍵被按下時,可以使用“休眠-喚醒”機制: ① APP 調用 read 等函數(shù)試圖讀取數(shù)據,比如讀取按鍵; ② APP 進入內核態(tài),也就是調用驅動中的對應函數(shù),發(fā)現(xiàn)有數(shù)據則復制到用戶空間并馬上返回; ③ 如果 APP 在內核態(tài),也就

    2024年02月16日
    瀏覽(52)
  • STM32MP157驅動開發(fā)——USB設備驅動

    STM32MP157驅動開發(fā)——USB設備驅動

    參考文章:【正點原子】I.MX6U嵌入式Linux驅動開發(fā)——Linux USB驅動 ??由于 USB 協(xié)議太過龐大和復雜,所以本節(jié)只對 STM32MP157 自帶的 USB 驅動進行使能和測試。詳細的 USB 接口和協(xié)議的介紹,可以參考原子哥的資料《USB2.0 協(xié)議中文版.pdf》和《USB3.0 協(xié)議中文版.pdf》。 ??USB 全

    2023年04月14日
    瀏覽(42)
  • STM32MP157驅動開發(fā)——Linux LCD驅動(上)

    STM32MP157驅動開發(fā)——Linux LCD驅動(上)

    ??LCD 是很常用的一個外設,通過 LCD 可以顯示圖片、界面UI等,提高人機交互的效率。STM32MP1 提供了一個 LTDC 接口用于連接 RGB 接口的液晶屏。本節(jié)就來學習如何使用這個接口。 ??LCD 全稱是 Liquid Crystal Display,也就是液晶顯示器,是現(xiàn)在最常用到的顯示器。網上對于 LCD

    2024年02月08日
    瀏覽(20)
  • STM32 Linux開發(fā)板丨STM32MP157開發(fā)板資料手冊+實戰(zhàn)教程+視頻教程

    STM32 Linux開發(fā)板丨STM32MP157開發(fā)板資料手冊+實戰(zhàn)教程+視頻教程

    iTOP-STM32MP157開發(fā)板是基于意法半導體STARM雙Cortex-A7核加單Cortex-M4核的一款多核異構處理器。Cortex-A7內核提供對開源操作系統(tǒng)Linux的支持,借助Linux系統(tǒng)龐大而豐富的軟件組件處理復雜應用。M4內核上運行對于實時性要求嚴格的應用。 開發(fā)板既有A7核,又有M4核,從學習者角度來看

    2024年02月12日
    瀏覽(16)
  • SQLite3移植STM32MP157 ARM開發(fā)板

    SQLite3移植STM32MP157 ARM開發(fā)板

    移植首先就得有源碼,從SQLite官網下載最新版源碼 下載地址 這里使用的環(huán)境為Ubuntu16 所以直接在Ubuntu下下載的。 下載完成后解壓文件 進入解壓后的目錄 進入后可以看到解壓出的源碼文件如下 配置生成Makefile 在源碼個目錄下執(zhí)行如下命令 –host為指定交叉編譯器為arm-linux-

    2024年02月07日
    瀏覽(17)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包