“NRF52832DK基础实验”的版本间的差异
(lcd) |
(lcd代码说明) |
||
第525行: | 第525行: | ||
==== 代码分析 ==== | ==== 代码分析 ==== | ||
− | |||
− | |||
开发者打开谷雨物联提供的peripheral_ghostyu文件夹中07_tft_spi_example工程(IAR工程)。 | 开发者打开谷雨物联提供的peripheral_ghostyu文件夹中07_tft_spi_example工程(IAR工程)。 | ||
在IAR的Workspace中点开Application,双击main.c文件,打开main.c。 | 在IAR的Workspace中点开Application,双击main.c文件,打开main.c。 | ||
+ | |||
+ | '''LCD驱动部分代码说明,在此不会进行说明。开发者可以查看《谷雨显示接口原理说明》,里面详细介绍了屏幕驱动部分。'''<syntaxhighlight lang="c" line="1"> | ||
+ | //****************************************************************************** | ||
+ | // fn :main | ||
+ | // | ||
+ | // brief : 主程序入口 | ||
+ | // | ||
+ | // param : none | ||
+ | // | ||
+ | // return : none | ||
+ | int main(void) | ||
+ | { | ||
+ | LED_Init(); //LED 初始化 | ||
+ | |||
+ | bsp_board_lcd_init(); | ||
+ | GUI_Init(); | ||
+ | for(uint8_t i = 0;;) | ||
+ | { | ||
+ | GUI_SetBkColor(color[i%3]); | ||
+ | GUI_Clear(); | ||
+ | GUI_DispStringAt("SPI lcd Test\r\n",0,0); | ||
+ | LED_Toggle(i++%3); | ||
+ | nrf_delay_ms(500); | ||
+ | } | ||
+ | } | ||
+ | </syntaxhighlight>在main函数中,bsp_board_lcd_init函数用于初始化SPI外设。在此例子中没有使用EasyDMA模式,而使用普通的SPI模式,具本的宏定义配置在SDK_CONFIG.H中。bsp_board_lcd_init函数中,配置SCK,MOSI,SS引脚,时钟频率,及SPI工作模式,字节方向等。NRF_DRV_SPI_DEFAULT_CONFIG是一个宏,定义了nrf_drv_spi_config_t的结构数据。<syntaxhighlight lang="c" line="1"> | ||
+ | //****************************************************************************** | ||
+ | // fn : bsp_board_lcd_init | ||
+ | // | ||
+ | // brife : init lcd hardware.ex spi, gpio | ||
+ | // | ||
+ | // param : opt -> 0 OR 1 | ||
+ | // | ||
+ | // return : none | ||
+ | void bsp_board_lcd_init(void) | ||
+ | { | ||
+ | nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG; | ||
+ | spi_config.ss_pin = LCD_SPI_SS_PIN; | ||
+ | //spi_config.miso_pin = SPI_MISO_PIN; //NOT USED | ||
+ | spi_config.mosi_pin = LCD_SPI_MOSI_PIN; | ||
+ | spi_config.sck_pin = LCD_SPI_SCK_PIN; | ||
+ | spi_config.frequency = NRF_DRV_SPI_FREQ_8M; | ||
+ | |||
+ | //block mode | ||
+ | nrf_drv_spi_init(&spi, &spi_config, NULL, NULL); | ||
+ | |||
+ | //Config the bl and mode pin to output | ||
+ | nrf_gpio_cfg_output(LCD_BL_PIN); | ||
+ | nrf_gpio_cfg_output(LCD_MODE_PIN); | ||
+ | } | ||
+ | </syntaxhighlight>NRF_DRV_SPI_DEFAULT_CONFIG宏定义内容。<syntaxhighlight lang="c" line="1"> | ||
+ | #define NRF_DRV_SPI_DEFAULT_CONFIG \ | ||
+ | { \ | ||
+ | .sck_pin = NRF_DRV_SPI_PIN_NOT_USED, \ | ||
+ | .mosi_pin = NRF_DRV_SPI_PIN_NOT_USED, \ | ||
+ | .miso_pin = NRF_DRV_SPI_PIN_NOT_USED, \ | ||
+ | .ss_pin = NRF_DRV_SPI_PIN_NOT_USED, \ | ||
+ | .irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY, \ | ||
+ | .orc = 0xFF, \ | ||
+ | .frequency = NRF_DRV_SPI_FREQ_4M, \ | ||
+ | .mode = NRF_DRV_SPI_MODE_0, \ | ||
+ | .bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST, \ | ||
+ | } | ||
+ | </syntaxhighlight> | ||
==== 实验现象 ==== | ==== 实验现象 ==== |
2019年7月8日 (一) 12:05的版本
nRF52832是Nordic公司推出一款高性能无线SOC芯片,在芯片上可以运行多种协议栈,包括蓝牙BLE,NFC,ANT,802.15.4G,其中BLE协议栈可以支持到BLE5.0。为此谷雨物联推出一款基于nRF52832芯片评估板,nRF52832DK。
nRF52832DK评估板上设计了丰富实用的外围设备。其中有4路LED,4路按键输入,一路MINI usb转UART,三路PWM RGB灯珠,一路有源蜂鸣器,一路光敏,一路振动马达,TFT显示器接口,NFC标签接口。
目录
1 nRF52832DK基础实验说明列表
方便开发者,更快,更容易上手nRF52832芯片的外设操作,为此我们提供和整理nRF52832DK外围电路实验说明。见下表所示。
实验名称 | 实验所需外设 | 实验简单说明 |
---|---|---|
01_LED亮灭实验 | GPIO | 熟悉GPIO操作 |
02_按键输入实验(poll) | GPIO | 熟悉GPIO操作 |
03_按键输入实验(int) | GPIO边沿中断 | 熟悉GPIO边沿中断 |
04_振动马达实验 | GPIO | 熟悉GPIO操作 |
05_蜂鸣器实验 | GPIO | 熟悉GPIO操作 |
06_RGB实验 | PWM | 熟悉PWM操作 |
07_TFT实验(tft_lcd_144,tft_lcd_130) | SPI | 熟悉SPI操作 |
08_UART收发实验 | UART | 熟悉UART操作 |
09_光照度实验 | ADC | 熟悉ADC操作 |
2 LED亮灭实验
LED亮灭实验是展示nRF52832的GPIO输出配置,使开发者更直观的了解GPIO输出。GPIO输出是熟悉一款MCU的开始。下面将简单的介绍并分析相关代码。在NRF52832DK评估板上有4路LED资源,分别处在PIN17,PIN18,PIN19,PIN20四个引脚上。LED电路原理图,如下图所示。其为低电平有效,即引脚为低电平时LED被点亮,引脚为高电平时LED熄灭。
2.1 代码分析
开发者打开谷雨物联提供的peripheral_ghostyu文件夹中01_led_blinkly工程(IAR工程)。
在IAR的Workspace中点开Application,双击main.c文件,打开main.c。
1 //******************************************************************************
2 // fn :main
3 //
4 // brief : 主程序入口
5 //
6 // param : none
7 //
8 // return : none
9 int main(void)
10 {
11
12 LED_Init();
13
14 for(;;)
15 {
16 //循环点亮熄灭LED,间隔500ms
17 for( uint8_t i = 0; i < LEDS_NUMBER ; i++)
18 {
19 nrf_gpio_pin_toggle(Leds[i]);
20 nrf_delay_ms(500);
21 }
22 }
23 }
其中LED_Init函数用于初始化LED引脚。将四路LED引脚初始化输出模式,并置高电平,即熄灭LED。
1 //******************************************************************************
2 // fn :LED_Init
3 //
4 // brief : 初始化LED引脚为输出模式,并熄灭LED
5 //
6 // param : none
7 //
8 // return : none
9 void LED_Init(void)
10 {
11 uint8_t i = 0;
12
13 //配置LED引脚为输出模式
14 nrf_gpio_range_cfg_output(LED_START, LED_STOP);
15
16 //置LED引脚为高电平,即LED灭
17 for(i = 0 ; i < LEDS_NUMBER; i++)
18 {
19 nrf_gpio_pin_set(Leds[i]);
20 }
21 }
LED_START,LED_STOP是两个宏,标记LED开始引脚到LED结束引脚范围。配合nrf_gpio_range_cfg_output函数,可实现批量设置。nrf_gpio_pin_set设置LED引脚输出高电平。
完成LED引脚配置,进入while循环。在循环中遍历所有的LED引脚,翻转引脚高低电平,达到闪烁的目的。nrf_delay_ms函数用于软件延时。nrf_gpio_pin_toggle对引脚电平进行翻转。参数是LED引脚。在nrf_gpio_pin_toggle内部,先读取引脚当前的高低电平状态,然后根据返回的状态进行取反,再设置OUT寄存器。
2.2 实验现象
硬件准备:
- Jlink-Lite仿真器或J-Link仿真器
- NRF52832DK评估板
编译工程,点击IAR IDE工具栏中绿色三角仿真按钮,IAR便会将程序下载到nRF52832中,点击全速运行即可。此时NRF52832的LED便会每500ms依次点亮LED;当四个LED全部点亮后,再以500ms依次熄灭LED,直到全部熄灭。
3 按键输入实验(poll)
01_LED亮灭实验是操作GPIO引脚输出,而本实验是操作GPIO的输入。利用GPIO输入引脚电平变化,来监测按键按下动作。在NRF52832DE评估板上,提供了四路按键资源,分别占用PIN13,PIN14,PIN15,PIN16四个引脚上。按键电路原理图,如下图所示。由原理图可知,按键是低电平有效。当按键按下引脚为低电平,释放时会高电平。注,按键引脚必须要使能引脚上拉功能,否则可能告成按键识别不可靠。
3.1 代码分析
开发者打开谷雨物联提供的peripheral_ghostyu文件夹中02_key_press工程(IAR工程)。
在IAR的Workspace中点开Application,双击main.c文件,打开main.c。
1 //******************************************************************************
2 // fn :main
3 //
4 // brief : 主程序入口
5 //
6 // param : none
7 //
8 // return : none
9 int main(void)
10 {
11
12 LED_Init(); //LED 初始化
13 BTN_Init(); //BTN 初始化
14
15 for(;;)
16 {
17 //循环点亮熄灭LED,间隔500ms
18 for( uint8_t i = 0; i < BUTTONS_NUMBER ; i++)
19 {
20 if(BTN_state_get(i))
21 {
22 LED_On(i);
23 }
24 else
25 {
26 LED_Off(i);
27 }
28
29 }
30 nrf_delay_ms(100);
31 }
32 }
在LED_Init函数中调用nrf_gpio_range_cfg_output,将初始化NRF52832DK评估板LED引脚。LED将GPIO引脚初始化为输出。BTN_Init函数中调用nrf_gpio_range_cfg_input按键初始化上拉输入。此实验中只是用GPIO输入,所以只能采用轮询的方式,周期性查询按键引脚电平状态。当按键按下,BTN_state_get函数返回true,否则返回false。
为增加互动性,将用4个LED分别指示4个按键状态。按键按下点亮LED,按键释放熄灭LED。其代码实现如while中的for循环。LED_On点亮指定LED,LED_Off熄灭LED。
3.2 实验现象
硬件准备:
- Jlink-Lite仿真器或J-Link仿真器
- NRF52832DK评估板
编译工程,点击IAR IDE工具栏中绿色三角仿真按钮,IAR便会将程序下载到nRF52832中,点击全速运行即可。此时NRF52832的LED是全灭状态。
- 按下SW1,LED1亮;释放SW1,LED1灭
- 按下SW2,LED2亮;释放SW2,LED2灭
- 按下SW3,LED3亮;释放SW3,LED3灭
- 按下SW3,LED4亮;释放SW4,LED4灭
4 按键中断输入实验(int)
02_按键输入实验是采用轮询方式不断查询引脚电平状态。引脚默认为高电平,当按下按键后,引脚会变成低电平。而此实验将使用nRF52832的GPIOTE边沿中断方式来监测按键动作。中断方式监测按键,带来了高灵敏度,高效率,同时也增加了按键按下不可靠性。主要原因按键按下会产生电平抖动。要求高可靠性可以为此要加入消抖。由02的原理图中可以见,没有硬件上的消抖,所以只能在驱动程序上进行消抖操作(此例程中没加入消抖)。
在例子中,使用了RF52832的GPIOTE功能,GPIOTE与GPIO使用上有所区别。但是如果一个引脚使用了GPIOTE功能,GPIO功能将不启作用,引脚上的所有操作将由GPIOTE支配,直到GPIOTE失能。
如果开发者要详细了解GPIOTE可以查看nRF52832的芯片手册《nRF52832_OPS.PDF》。《nRF52832 Objective Product Specification v0.6.3》
4.1 代码分析
开发者打开谷雨物联提供的peripheral_ghostyu文件夹中03_key_press_int工程(IAR工程)。
在IAR的Workspace中点开Application,双击main.c文件,打开main.c。
1 //******************************************************************************
2 // fn :main
3 //
4 // brief : 主程序入口
5 //
6 // param : none
7 //
8 // return : none
9 int main(void)
10 {
11 GPIOTE_Init();
12
13 LED_Init(); //LED 初始化
14 BTN_Init(); //BTN 初始化
15
16 for(;;)
17 {
18 //循环,间隔100ms
19 nrf_delay_ms(100);
20 }
21 }
在例程中使用了GPIOTE功能,所以在main函数开始处就初始化GPIOTE驱动(在使用gpiote相关函数之前,一定要先调用gpiote初始化函数nrf_drv_gpiote_init,否则可能产生不可预知问题)。接着配置LED引脚。在代码中提供两种方式,一种与02实验一至,另一种是gpiote方式。它们通过LED_GPOITE宏进行选择编译。这里主要介绍GPIOTE方式。
1 //******************************************************************************
2 // fn :LED_Init
3 //
4 // brief : 初始化LED引脚为输出模式,并熄灭LED
5 //
6 // param : none
7 //
8 // return : none
9 void LED_Init(void)
10 {
11 #if defined(LED_GPIOTE)
12 uint8_t i = 0;
13
14 //配置LED引脚为输出模式
15 nrf_drv_gpiote_out_config_t out_config = GPIOTE_CONFIG_OUT_SIMPLE(true);
16
17 //置LED引脚为高电平,即LED灭
18 for(i = 0 ; i < LEDS_NUMBER; i++)
19 {
20 nrf_drv_gpiote_out_init(Leds[i], &out_config);
21 }
22 #else
23 uint8_t i = 0;
24
25 //配置LED引脚为输出模式
26 nrf_gpio_range_cfg_output(LED_START, LED_STOP);
27
28 //置LED引脚为高电平,即LED灭
29 for(i = 0 ; i < LEDS_NUMBER; i++)
30 {
31 nrf_gpio_pin_set(Leds[i]);
32 }
33 #endif
34 }
nRF52832的GPIOTE只有8个通道,所以每个通道都要进行配置。在LED引脚中,选择简单的输出配置即GPIOTE_CONFIG_OUT_SIMPLE,它是一个宏。是对nrf_drv_gpiote_out_config_t类型成员初始化结构体。其中参数表示引脚配置成GPIOTE时默认引脚状态。 nrf_drv_gpiote_out_init函数将对指定引脚进行GPIOTE_CONFIG_OUT_SIMPLE配置。
1 //******************************************************************************
2 // fn :Btn_Init
3 //
4 // brief : 初始化Btn引脚为输入,全边沿敏感模式
5 //
6 // param : none
7 //
8 // return : none
9 void BTN_Init(void)
10 {
11 //创建引脚配置结构
12 nrf_drv_gpiote_in_config_t btn_config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
13 btn_config.pull = NRF_GPIO_PIN_PULLUP;
14 //配置Btn引脚为边沿敏感
15 for(uint8_t i = 0 ; i < BUTTONS_NUMBER ; i++)
16 {
17 nrf_drv_gpiote_in_init(Btns[i], &btn_config, BTN_pin_handler);
18 nrf_drv_gpiote_in_event_enable(Btns[i], true);
19 }
20 }
BTN_Init函数是对按键的引脚进行TOGGLE sense输入配置。其中GPIOTE_CONFIG_IN_SENSE_TOGGLE也宏,是对nrf_drv_gpiote_in_config_t类型成员初始化结构体。参数true表示使用IN_EVENT配置,而非PORT_EVENT。由于按键外部硬件没有上拉,所以这里要配置成上拉,即pull成员变量设置成NRF_GPIO_PIN_PULLUP。
nrf_drv_gpiote_in_init函数将按键引脚配置成GPIOTE_CONFIG_IN_SENSE_TOGGLE模式,同时要传入中断回调函数。最后要调用nrf_drv_gpiote_in_event_enable函数使能引脚IN_EVENT。
中断方式采集按键,是一种异步方式,所以在回调函数中要进行逻辑上的处理。然而在这个例程中,四个按键使用同一个回调函数。所以要在回调函数中要进行按按键识别,包括按键位置识别,还有按键动作。
1 //******************************************************************************
2 // fn :BTN_pin_handler
3 //
4 // brief : BTN引脚边沿中断回调函数
5 //
6 // param : pin -> 引脚号
7 // action -> 极性变化形为
8 //
9 // return : none
10 void BTN_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
11 {
12 bool flag = false;
13 switch(pin)
14 {
15 case BUTTON_1:
16 case BUTTON_2:
17 case BUTTON_3:
18 case BUTTON_4:
19 flag = true;
20 break;
21 default:
22 break;
23 }
24 if(flag)
25 {
26 uint8_t idx = BTN_Pin_To_Idx(pin);
27 //读取pin电平状态
28 if(nrf_drv_gpiote_in_is_set(pin))
29 {
30 LED_Off(idx); //按键释放,熄灭LED
31 }
32 else
33 {
34 LED_On(idx); //按键按下,点亮LED
35 }
36 }
37 }
其中flag是有效按键动作的标记。只有是BUTTON_1,BUTTON_2,BUTTON_3,BUTTON_4按键才是有效动作。通过nrf_drv_gpiote_in_is_set查询引脚当前电平状态,确定按键是按下,还是释放动作。并根据按键动作,点亮或熄灭LED。
4.2 实验现象
硬件准备:
- Jlink-Lite仿真器或J-Link仿真器
- NRF52832DK评估板
编译工程,点击IAR IDE工具栏中绿色三角仿真按钮,IAR便会将程序下载到nRF52832中,点击全速运行即可。此时NRF52832的LED是全灭状态。
- 按下SW1,LED1亮;释放SW1,LED1灭
- 按下SW2,LED2亮;释放SW2,LED2灭
- 按下SW3,LED3亮;释放SW3,LED3灭
- 按下SW3,LED4亮;释放SW4,LED4灭
5 振动马达实验
在NRF52832DK评估板上,设计有一路振动马达,方便开发者对蓝牙ANCS开发。其直流马达的工作原理不用多介绍,只要给它提供直流电即可工作。MOTOR端的高低电平,将会另三极管打开与关闭,从而控制振动马达工作。MOTOR是连接在nrf52832的P0.12引脚上。
5.1 代码分析
开发者打开谷雨物联提供的peripheral_ghostyu文件夹中04_motor_example工程(IAR工程)。
在IAR的Workspace中点开Application,双击main.c文件,打开main.c。
1 //******************************************************************************
2 // fn :main
3 //
4 // brief : 主程序入口
5 //
6 // param : none
7 //
8 // return : none
9 int main(void)
10 {
11 Motor_Init();
12 LED_Init();
13
14 for(;;)
15 {
16 //循环点亮熄灭LED,间隔500ms
17 for( uint8_t i = 0; i < LEDS_NUMBER ; i++)
18 {
19 nrf_gpio_pin_toggle(Leds[i]);
20 nrf_gpio_pin_toggle(BSP_MOTOR_0);
21 nrf_delay_ms(500);
22 }
23 }
24 }
main函数与《01_LED亮灭实验》十相似,只是在其基础上添加了MOTOR相关的代码。
Motor_Init函数是对MOTOR引脚进行输出初始化。nrf_gpio_pin_toggle函数是对MOTOR引脚的电平进行翻转,从而输出高低电平,即马达就会振动与关闭。
5.2 实验现象
硬件准备:
- Jlink-Lite仿真器或J-Link仿真器
- NRF52832DK评估板
编译工程,点击IAR IDE工具栏中绿色三角仿真按钮,IAR便会将程序下载到nRF52832中,点击全速运行即可。此时NRF52832的LED便会每500ms依次点亮LED;当四个LED全部点亮后,再以500ms依次熄灭LED,直到全部熄灭。期间,每一次LED状态改变,其马达就会工作一次或关闭一次,间隔时间是500ms。
6 蜂鸣器实验
在NRF52832DK评估板上,设计有一路有源蜂鸣器,方便开发者对蓝牙ANCS开发。其蜂鸣器的工作原理不用多介绍,只要给它提供直流电即可工作。BUZZER端的高低电平,将会另三极管打开与关闭,从而控制蜂鸣器工作。BUZZER是连接在nrf52832的P0.11引脚上。
6.1 代码分析
开发者打开谷雨物联提供的peripheral_ghostyu文件夹中05_buzzer_example工程(IAR工程)。
在IAR的Workspace中点开Application,双击main.c文件,打开main.c。
1 //******************************************************************************
2 // fn :main
3 //
4 // brief : 主程序入口
5 //
6 // param : none
7 //
8 // return : none
9 int main(void)
10 {
11 Buzzer_Init();
12 LED_Init();
13
14 for(;;)
15 {
16 //循环点亮熄灭LED,间隔500ms
17 for( uint8_t i = 0; i < LEDS_NUMBER ; i++)
18 {
19 nrf_gpio_pin_toggle(Leds[i]);
20 nrf_gpio_pin_toggle(BSP_BUZZER_0);
21 nrf_delay_ms(500);
22 }
23 }
24 }
main函数与《04_振动马达实验》十相似,只是将MOTOR相关代码替换成了BUZZER代码。
Buzzer_Init函数是对BUZZER引脚进行输出初始化。nrf_gpio_pin_toggle函数是对BUZZER引脚的电平进行翻转,从而输出高低电平,即蜂鸣器就会工作与关闭。
6.2 实验现象
硬件准备:
- Jlink-Lite仿真器或J-Link仿真器
- NRF52832DK评估板
编译工程,点击IAR IDE工具栏中绿色三角仿真按钮,IAR便会将程序下载到nRF52832中,点击全速运行即可。此时NRF52832的LED便会每500ms依次点亮LED;当四个LED全部点亮后,再以500ms依次熄灭LED,直到全部熄灭。期间,每一次LED状态改变,其蜂鸣器就会工作一次或关闭一次,间隔时间是500ms。
7 RGB实险
在NRF52832DK评估板上,提供一个RGB调色灯。方便开发者利用NRF52832开发蓝牙RGB灯。RGB调光灯采用三路PWM分别控制三色灯的亮度达到调色目标。在NRF52832芯片中有三个PWM外设,每个外设有4路PWM。NRF52832的PWM外设细节,可以查阅芯片手册。
从原理图可以看出,每路灯都是由三极管控制,所以控制端高电平表示打开,低电平表示关闭。
7.1 代码分析
开发者打开谷雨物联提供的peripheral_ghostyu文件夹中06_rgb_example工程(IAR工程)。
在IAR的Workspace中点开Application,双击main.c文件,打开main.c。
1 //******************************************************************************
2 // fn :main
3 //
4 // brief : 主程序入口
5 //
6 // param : none
7 //
8 // return : none
9 int main(void)
10 {
11 GPIOTE_Init();
12
13 LED_Init(); //LED 初始化
14 BTN_Init(); //BTN 初始化
15 RGB_PwmInit();
16
17 for(;;)
18 {
19 //循环,间隔100ms
20 nrf_delay_ms(100);
21 }
22 }
在main函数中,RGB_PwmInit是初始化PWM函数。 在RGB_PwmInit函数中,配置了pwm输出引脚,时钟频率,计数方式等。
1 //******************************************************************************
2 // fn :RGB_PwmInit
3 //
4 // brief : 初始化RGB pwm模式
5 //
6 // param : none
7 //
8 // return : none
9 void RGB_PwmInit(void)
10 {
11 nrf_drv_pwm_config_t const rgb_config =
12 {
13 .output_pins =
14 {
15 RGB_PWM_R , // channel 0
16 RGB_PWM_G , // channel 1
17 RGB_PWM_B , // channel 2
18 NRF_DRV_PWM_PIN_NOT_USED // channel 3
19 },
20 .irq_priority = APP_IRQ_PRIORITY_LOWEST,
21 .base_clock = NRF_PWM_CLK_1MHz,
22 .count_mode = NRF_PWM_MODE_UP, //向上计数方式
23 .top_value = NRFX_PWM_DEFAULT_CONFIG_TOP_VALUE,
24 .load_mode = NRF_PWM_LOAD_WAVE_FORM, //WaveForm加载方式
25 .step_mode = NRF_PWM_STEP_AUTO
26 };
27
28 nrf_drv_pwm_init(&m_RGB, &rgb_config, rgb_pwm_handler);
29 nrf_drv_pwm_simple_playback(&m_RGB, &m_rgb_seq, 1,
30 NRF_DRV_PWM_FLAG_LOOP);
31 }
nrf_drv_pwm_config_t 是初始化PWM外设配置结构体。在其中设置的pwm输出引脚,中断优先级,时钟频率,计数方式,计数长度,比较值加载方式等。调用nrf_drv_pwm_init初始化函数,传入事件回调函数rgb_pwm_handler,方便开发者监视相关事件及参数修改。在此例程中,回调数主要用来修改相应PWM通道的比较值,实现PWM的占空比从0%到100%变化。改变通道数是通过按键来修改RGB_OP_CH值。
1 //******************************************************************************
2 // fn :rgb_pwm_handler
3 //
4 // brief : rgb pwm事件回调函数
5 //
6 // param : none
7 //
8 // return : none
9 static void rgb_pwm_handler(nrf_drv_pwm_evt_type_t event_type)
10 {
11 if (event_type == NRF_DRV_PWM_EVT_FINISHED)
12 {
13 uint16_t *p_channel = NULL;
14 //获取当前wm通道数值地址
15 switch(RGB_OP_CH)
16 {
17 case PWM_R:
18 p_channel = &m_rgb_seq_values.channel_0;
19 break;
20 case PWM_G:
21 p_channel = &m_rgb_seq_values.channel_1;
22 break;
23 case PWM_B:
24 p_channel = &m_rgb_seq_values.channel_2;
25 break;
26 default:
27 return;
28 break;
29 }
30 if(value_dir) //控制修改数据方向。
31 {
32 //UP
33 *p_channel += RGB_MIN_STEP;
34
35 if(*p_channel >= m_rgb_seq_values.counter_top)
36 {
37 *p_channel = m_rgb_seq_values.counter_top;
38 value_dir = false;
39 }
40 }
41 else
42 {
43 //Down
44 *p_channel -= RGB_MIN_STEP;
45 if(*p_channel >= m_rgb_seq_values.counter_top)
46 {
47 *p_channel = 0;
48 value_dir = true;
49 }
50 }
51 }
52 }
RGB_MIN_STEP是每次变化的步长,这里设置为1。value_dir是控制修改数据的方向,当比较值达到最大值或最小值时就会更改方向,使比较值向相反的方向增加或减小。
7.2 实验现象
硬件准备:
- Jlink-Lite仿真器或J-Link仿真器
- NRF52832DK评估板
编译工程,点击IAR IDE工具栏中绿色三角仿真按钮,IAR便会将程序下载到nRF52832中,点击全速运行即可。会发现评估板的RGB灯会不断的改变颜色。原因是PWMR路的PWM的占空化不断变化所致,如下图PWR所示,而其他二路PWM占空比保持不变。
按键S1,S2,S3分别控制PWM的R,G,B分量。而S4则会暂停PWM的占空比,直到S1,S2,S3按下。
8 TFT实验(tft_lcd_144,tft_lcd_130)
NRF52832DK评估板上,提供一路LCD接口。使用NRF52832的SPI外设。在SPI外设中有两种工作模式,分别为EasyDMA方式,普通DMA模式。使用DMA模式时,开发者要注意。所有使用SPI发送的数据,都必须在RAM中,否则将发生错误。SPI的CPOL与CPHA具体参数及意义,这里将不再详述。详细的细节部分,开发者可以查阅NRF52832的芯片手册。
DIS_BL与DIS_D/C引脚,是TFT屏的控制引脚。DIS_BL是控制背光,DIS_D/C是控制收发数据的属性,是命令数据,还是颜色数据。
8.1 代码分析
开发者打开谷雨物联提供的peripheral_ghostyu文件夹中07_tft_spi_example工程(IAR工程)。
在IAR的Workspace中点开Application,双击main.c文件,打开main.c。
LCD驱动部分代码说明,在此不会进行说明。开发者可以查看《谷雨显示接口原理说明》,里面详细介绍了屏幕驱动部分。
1 //******************************************************************************
2 // fn :main
3 //
4 // brief : 主程序入口
5 //
6 // param : none
7 //
8 // return : none
9 int main(void)
10 {
11 LED_Init(); //LED 初始化
12
13 bsp_board_lcd_init();
14 GUI_Init();
15 for(uint8_t i = 0;;)
16 {
17 GUI_SetBkColor(color[i%3]);
18 GUI_Clear();
19 GUI_DispStringAt("SPI lcd Test\r\n",0,0);
20 LED_Toggle(i++%3);
21 nrf_delay_ms(500);
22 }
23 }
在main函数中,bsp_board_lcd_init函数用于初始化SPI外设。在此例子中没有使用EasyDMA模式,而使用普通的SPI模式,具本的宏定义配置在SDK_CONFIG.H中。bsp_board_lcd_init函数中,配置SCK,MOSI,SS引脚,时钟频率,及SPI工作模式,字节方向等。NRF_DRV_SPI_DEFAULT_CONFIG是一个宏,定义了nrf_drv_spi_config_t的结构数据。
1 //******************************************************************************
2 // fn : bsp_board_lcd_init
3 //
4 // brife : init lcd hardware.ex spi, gpio
5 //
6 // param : opt -> 0 OR 1
7 //
8 // return : none
9 void bsp_board_lcd_init(void)
10 {
11 nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
12 spi_config.ss_pin = LCD_SPI_SS_PIN;
13 //spi_config.miso_pin = SPI_MISO_PIN; //NOT USED
14 spi_config.mosi_pin = LCD_SPI_MOSI_PIN;
15 spi_config.sck_pin = LCD_SPI_SCK_PIN;
16 spi_config.frequency = NRF_DRV_SPI_FREQ_8M;
17
18 //block mode
19 nrf_drv_spi_init(&spi, &spi_config, NULL, NULL);
20
21 //Config the bl and mode pin to output
22 nrf_gpio_cfg_output(LCD_BL_PIN);
23 nrf_gpio_cfg_output(LCD_MODE_PIN);
24 }
NRF_DRV_SPI_DEFAULT_CONFIG宏定义内容。
1 #define NRF_DRV_SPI_DEFAULT_CONFIG \
2 { \
3 .sck_pin = NRF_DRV_SPI_PIN_NOT_USED, \
4 .mosi_pin = NRF_DRV_SPI_PIN_NOT_USED, \
5 .miso_pin = NRF_DRV_SPI_PIN_NOT_USED, \
6 .ss_pin = NRF_DRV_SPI_PIN_NOT_USED, \
7 .irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY, \
8 .orc = 0xFF, \
9 .frequency = NRF_DRV_SPI_FREQ_4M, \
10 .mode = NRF_DRV_SPI_MODE_0, \
11 .bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST, \
12 }