本帖最后由 jinglixixi 于 2017-11-19 14:01 编辑
自动恒温控制系统的实现 (2) 下位机的开发平台选取KEIL V4.0,并由C51编程来实现功能要求。
相关的功能程序如下: 1. 液晶屏显示程序 2. 参数设置程序 3. 温度检测与控制程序 4. 串行通讯程序
液晶屏的连接与显示程序 LCD5110为3.3V的显示器件,并以SPI的通讯方式来进行控制,为节省管脚,直接将CS引脚以GND相连,其信号引脚的连接情况如下: SCLK--PC.3 DIN --PC.2 DC --PC.1 RST --PC.0 此外,可以将用背光引脚与一个GPIO口相连以控制背光的亮灭。
定义LCD5110信号引脚输出高低电平的语句如下: #define SetLCD_SCLK_High() { GPIO_WriteBit(GPIOC, GPIO_Pin_3, Bit_SET);} #define SetLCD_SCLK_Low() { GPIO_WriteBit(GPIOC, GPIO_Pin_3, Bit_RESET);}
#define SetLCD_SDIN_High() { GPIO_WriteBit(GPIOC, GPIO_Pin_2, Bit_SET);} #define SetLCD_SDIN_Low() { GPIO_WriteBit(GPIOC, GPIO_Pin_2, Bit_RESET);}
#define SetLCD_DC_High() { GPIO_WriteBit(GPIOC, GPIO_Pin_1, Bit_SET);} #define SetLCD_DC_Low() { GPIO_WriteBit(GPIOC, GPIO_Pin_1, Bit_RESET);}
#define SetLCD_RST_High() { GPIO_WriteBit(GPIOC, GPIO_Pin_0, Bit_SET);} #define SetLCD_RST_Low() { GPIO_WriteBit(GPIOC, GPIO_Pin_0, Bit_RESET);}
配置相应引脚的函数如下: void GPIO_Configuration(void)
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3|GPIO_Pin_2|GPIO_Pin_1|GPIO_Pin_0; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
对应的初始化程序为: void LCD_Init(void)
{
SetLCD_RST_Low();
delay_1us();
SetLCD_RST_High();
delay_1us();
delay_1us();
LCD_write_CMD(0x21);
LCD_write_CMD(0xc0);
LCD_write_CMD(0x06);
LCD_write_CMD(0x13);
LCD_write_CMD(0x20);
LCD_Clear();
LCD_write_CMD(0x0c);
}
实现初始显示界面的语句如下: GPIO_Configuration();
GPIO_WriteBit(GPIOC, GPIO_Pin_9, Bit_SET);
LCD_Init();
LCD_Clear();
LCD_write_english_string(0,0,"nokia5110 v1.0");
LCD_write_english_string(0,2,"x1= ");
LCD_write_english_string(0,3,"x2= ");
LCD_write_english_string(0,4,"temp= ");
LCD_set_XY(42,2);
LCD_write_char(i+0x30);
其界面效果如图2所示,由于当前温度低于温度下限,故加热器应开启以蓝色LED指示。 图2 界面显示效果
参数设置及程序 参数设置在温控系统中是十分重要的,否则温控器只能对某个固定温度区域进行控制。 为简化设计,这里是采用软按键来进行参数设置,它共有4个键,分别对应+1、-1、移位和确认处理。 4个键位分别与PB2、PB10、PB11、PB12相连,其引脚配置函数如下: void Key_IN(void)
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
实现上下限设置的程序如下: f==2;
while(f)
{
if(f==2) LCD_set_XY(42,2);
if(f==1) LCD_set_XY(42,3);
if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12)==0)
{
i--;
}
if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10)==0) // 确认键
{
if(f==1)
{
x2=i;
f=0;
}
if(f==2)
{
x1=i;
i=0;
f=1;
LCD_set_XY(42,3);
}
}
if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11)==0)
{
i++;
}
if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_2)==0)
{
i=i*10;
}
LCD_write_char(i/1000+0x30);
LCD_write_char(i%1000/100+0x30);
LCD_write_char(i%100/10+0x30);
LCD_write_char('.');
LCD_write_char(i%10+0x30);
for(k=0;k<20;k++)
{
Delay(60000);
}
}
温度检测与控制 DS18B20是一种使用广泛的单总线器件,其实它还有一种防水型的封装形式,如图3所示。由于手头没有就暂时用塑料封装的吧。 图3 防水型DS18B20
与DS18B20相连的引脚是PC4,由于该温度传感器只有一条数据引脚,故分时进行输入和输出处理,其相应的引脚配置函数如下: void DS18B20_IO_IN(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
void DS18B20_IO_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 ;//4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
实现温度检测与控制的程序如下: while (1)
{
DS18B20_Convert();
tempL = DS18B20_Read_Byte(); // LSB
tempH = DS18B20_Read_Byte(); // MSB
j=tempH*16+tempL/16;
LCD_set_XY(42,4);
LCD_write_char(j/100+0x30);
LCD_write_char(j%100/10+0x30);
LCD_write_char(j%10+0x30);
LCD_write_char('.');
LCD_write_char((tempL%16)*10/16+0x30);
i=j*10+(tempL%16)*10/16;
if(i>=x1) GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_RESET);
if(i<=x2) GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_SET);
Delay(5000);
}
由于手头的电加热棒还未找到,目前只以指示灯来模拟继电器的工作状态变化,后续再将继电器和加热棒接上验证一下控制效果。图4为温度超过上限,关闭加热器即关闭蓝色LED。通过模拟验证可发现,检测与反应的精度可达0.1度,要想达到控制的高精度就要看控制算法了。
此外,为了上传数据来绘制波形图,还需提交串行通讯的功能,并为指令的发送提供支持。 图4 温度模拟控制
|