由于在开发板上已为相应的数据采集通道配置了电位器来供模拟信号检测,为此可利用这些通道进行模拟量的采集和限值控制等测试。但在进行温度等模拟信号采集时,则应尽量避开这些通道的使用,因为这些电位器会成为引入外部传感器信号的障碍。当然,在万不得已的情况下,也可考虑去除相应的电位器来引入外部传感器信号。
1. 采集通道
开发板上所提供的采集通道,见图1所示。
图1 数据采集通道电路
具体到例程所使用的采集通道则是ADC0,所使用的引脚则为PA1,在测试时调节RV2即可起到改变模拟信号的目的。
2. 数据采集功能验证
为验证ADC的数据采集功能,可在ADC0数据采集的基础上添加OLED屏来实现数据的显示功能。
之所以采用OLED屏作显示,而不直接使用板载的LCD屏是因为该显示屏所占用的引脚资源过多,且在与板载的数据采集通道配合是会出现严重的干扰现象,见图2所示。
图2 互绕现象即使自行编写了LCD屏的显示程序,在与数据采集通道相配合时,也会出现采集低电平时显示较为正常,而在采集高电平时出现显示不清的问题。似乎是LCD屏占用了数据采集的引脚,一旦引脚的电位升高就会导致LCD屏的异常。最终的解决之道是避让开LCD屏所占用的引脚,同时又能进行数据采集。
图3 低电平显示效果
在最终的问题解决之前,还是采用一种效率比较高的方式来显示为好。
2. 数据采集功能验证
为验证ADC的数据采集功能,可在ADC0数据采集基础上通过添加OLED屏来显示数据。
该OLED屏是一款0.96寸显示屏,采用I2C接口,其显示分辨率为160*80,它与开发板的连接关系为:
SCL---PB10
SDA---PB11
这2个引脚输出高低电平的语句定义为:
#define SCL_high GPIO_WriteBit(GPIOB, GPIO_PIN_10, 1u)
#define SCL_low GPIO_WriteBit(GPIOB, GPIO_PIN_10, 0u);
#define SDA_high GPIO_WriteBit(GPIOB, GPIO_PIN_11, 1u);
#define SDA_low GPIO_WriteBit(GPIOB, GPIO_PIN_11, 0u);
对引脚的配置函数为:
void Init_oled(void){ gpio_init.Pins = GPIO_PIN_10; gpio_init.PinMode = GPIO_PinMode_Out_PushPull; gpio_init.Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &gpio_init); GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_15); gpio_init.Pins = GPIO_PIN_11; gpio_init.PinMode = GPIO_PinMode_Out_PushPull; gpio_init.Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &gpio_init); GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_15); }
复制代码以GPIO口模拟I2C方式字节数据的函数为:
void Write_IIC_Byte(unsigned char IIC_Byte){ unsigned char i; unsigned char m,da; da=IIC_Byte; SCL_low; for(i=0;i<8;i++) { m=da; m=m&0x80; if(m==0x80) { SDA_high; } else SDA_low; da=da<<1; del_t(20); SCL_high; del_t(20); SCL_low; del_t(20); } }
复制代码其验证数据采集及显示功能的主程序为:
int main(void){ uint32_t u,i,f; BOARD_Init(); Init_oled(); OLED_Init(); OLED_Clear(); OLED_ShowString(10,0,"EVB-L0136",16); OLED_ShowString(10,4,"ADC_1: ",16); OLED_ShowString(10,6,"U= mV",16); app_adc_init(); while (1) { printf("adc_val= %u\r\n", (unsigned)(app_adc_run_conv() & 0xFFF)); u=(unsigned)(app_adc_run_conv() & 0xFFF); OLED_ShowNum(58,4,u,5,16); u=3300*u/4095; OLED_ShowNum(26,6,u,5,16); app_delay(1000); } }
复制代码经程序的编译下载,通过调节电位器RV3,即可观察到数值的变化。
3.参数设置及控制
在温控过程中,离不开控制参数的数值,为此可利用板载的按键来实现,其按键和LED的电路如图4所示。
图4 按键和LED电路
为此,对按键所用引脚的配置函数为:
void Init_key(void){ gpio_init.Pins = GPIO_PIN_2; gpio_init.PinMode = GPIO_PinMode_In_PullDown; gpio_init.Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &gpio_init); GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_15); gpio_init.Pins = GPIO_PIN_5; gpio_init.PinMode = GPIO_PinMode_In_PullUp; gpio_init.Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &gpio_init); GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_15); gpio_init.Pins = GPIO_PIN_5; gpio_init.PinMode = GPIO_PinMode_In_PullUp; gpio_init.Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD, &gpio_init); GPIO_PinAFConf(GPIOD, gpio_init.Pins, GPIO_AF_15); gpio_init.Pins = GPIO_PIN_8; gpio_init.PinMode = GPIO_PinMode_In_PullUp; gpio_init.Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &gpio_init); GPIO_PinAFConf(GPIOA, gpio_init.Pins, GPIO_AF_15); }
复制代码对红色和黄色2个LED引脚的配置函数为:
void Init_led(void){ gpio_init.Pins = GPIO_PIN_9; gpio_init.PinMode = GPIO_PinMode_Out_PushPull; gpio_init.Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &gpio_init); GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_15); gpio_init.Pins = GPIO_PIN_0; gpio_init.PinMode = GPIO_PinMode_Out_PushPull; gpio_init.Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &gpio_init); GPIO_PinAFConf(GPIOC, gpio_init.Pins, GPIO_AF_0); GPIO_WriteBit(GPIOB, GPIO_PIN_9, 1u); GPIO_WriteBit(GPIOC, GPIO_PIN_0, 1u); }
复制代码以此为基础,通过下面的主程序可完成参数的设置及数据的采集和显示。
int main(void){ uint32_t u,i,f; BOARD_Init(); Init_oled(); OLED_Init(); OLED_Clear(); OLED_ShowString(10,0,"EVB-L0136",16); OLED_ShowString(10,2,"max:",16); OLED_ShowString(10,4,"ADC_1: ",16); OLED_ShowString(10,6,"U= mV",16); f=1; Init_key(); Init_led(); GPIO_WriteBit(GPIOB, GPIO_PIN_9, 1u); i=0; while (f) { if(GPIO_ReadInDataBit(GPIOB, GPIO_PIN_2)==1) i=i-1; // K1 if(GPIO_ReadInDataBit(GPIOD, GPIO_PIN_5)==0) i=(i+1)%100; // K2 if(GPIO_ReadInDataBit(GPIOA, GPIO_PIN_8)==0) i=(i*10)%100; // K3 if(GPIO_ReadInDataBit(GPIOB, GPIO_PIN_5)==0) f=0; // K4 OLED_ShowNum(42,2,i,5,16); app_delay(20); } app_adc_init(); while (1) { printf("adc_val= %u\r\n", (unsigned)(app_adc_run_conv() & 0xFFF)); u=(unsigned)(app_adc_run_conv() & 0xFFF); OLED_ShowNum(58,4,u,5,16); u=3300*u/4095; if(u<i) { GPIO_WriteBit(GPIOB, GPIO_PIN_9, 0u); } if(u>(i+2)) { GPIO_WriteBit(GPIOB, GPIO_PIN_9, 1u); } OLED_ShowNum(26,6,u,5,16); app_delay(1000); } }
复制代码该程序的运行效果如图5和图6所示,说明功能设计正确。
图5 加热状态
图6释热状态
后面,将添加NTC热敏电阻来实现温度的检测和控制。