|
阅读:0回复:1
求助,一个基于51单片机的温控系统制作QAQ
[i=s] 本帖最后由 羽木 于 2015-1-17 21:30 编辑
[size=12.0pt]大一狗一枚,刚进大学就要弄那么麻烦的东西#29m 感觉人生充满了挑战呐#31m 虽然已经弄好了一份程序,但总感觉写的真是不太好呐#7m 就来这里找大神求助了#28m 帮帮忙吖~#5m [size=12.0pt][size=12.0pt] 设计制作一个程控加热器,能根据预定的温度--时间曲线根据加热,其示意图在下面附件。 [p=null, 0, left]要求 (1)能显示控制温度和实际工作温度(用的是oled的显示屏,下附上显示程序);[/p][size=12.0pt](2)可用键盘设定工作温度,温控误差要求小于±2℃;(使用矩阵键盘) [size=12.0pt](3)温度低于30℃时,风扇停止工作,加热器开始加热;当温度高于70℃,应切断加热器,并接通风扇开始散热。(加热使用的是热电半导体制冷组件) [p=null, 0, left](4)到达预定温度、上下限温度时能声光报警; [/p][p=null, 0, left] (5)能显示风扇转速(打算用霍尔元件来弄);[/p][size=12.0pt](6)加热功率可调; [size=12.0pt](7)具有程控加热功能,能按预定的加热曲线加热; [size=12.0pt](8)温控误差要求小于±1℃ [size=12.0pt](9)其他。(这个可以不用) [size=12.0pt] [size=12.0pt] [size=12.0pt] [size=10.0pt]// ---------------------------------------------------------------- [size=10.0pt]// GND [size=10.0pt]电源地 [size=10.0pt]// VCC [size=10.0pt]接5V或3.3v电源 [size=10.0pt]// D0 P1^0[size=10.0pt](SCL) [size=10.0pt]// D1 P1^1[size=10.0pt](SDA) [size=10.0pt]// RES [size=10.0pt]接P12 [size=10.0pt]// DC [size=10.0pt]接P13 [size=10.0pt]// CS [size=10.0pt]接P14 [size=10.0pt]// ---------------------------------------------------------------- [size=10.0pt]#include"oled.h" [size=10.0pt]#include<usart.h> [size=10.0pt]#include"oledfont.h" [size=10.0pt]#include"delay.h" [size=10.0pt]//OLED[size=10.0pt]的显存 [size=10.0pt]//[size=10.0pt]存放格式如下. [size=10.0pt]//[0]01 2 3 ... 127 [size=10.0pt]//[1]01 2 3 ... 127 [size=10.0pt]//[2]01 2 3 ... 127 [size=10.0pt]//[3]01 2 3 ... 127 [size=10.0pt]//[4]01 2 3 ... 127 [size=10.0pt]//[5]01 2 3 ... 127 [size=10.0pt]//[6]01 2 3 ... 127 [size=10.0pt]//[7]01 2 3 ... 127 [size=10.0pt] [size=10.0pt]#if OLED_MODE==1 [size=10.0pt]//[size=10.0pt]向SSD1106写入一个字节。 [size=10.0pt]//dat:[size=10.0pt]要写入的数据/命令 [size=10.0pt]//cmd:[size=10.0pt]数据/命令标志0,表示命令;1,表示数据; [size=10.0pt]voidOLED_WR_Byte(u8 dat,u8 cmd) [size=10.0pt]{ [size=10.0pt] DATAOUT(dat); [size=10.0pt] if(cmd) [size=10.0pt] OLED_DC_Set(); [size=10.0pt] else [size=10.0pt] OLED_DC_Clr(); [size=10.0pt] OLED_CS_Clr(); [size=10.0pt] OLED_WR_Clr(); [size=10.0pt] OLED_WR_Set(); [size=10.0pt] OLED_CS_Set(); [size=10.0pt] OLED_DC_Set(); [size=10.0pt]} [size=10.0pt]#else [size=10.0pt]//[size=10.0pt]向SSD1306写入一个字节。 [size=10.0pt]//dat:[size=10.0pt]要写入的数据/命令 [size=10.0pt]//cmd:[size=10.0pt]数据/命令标志0,表示命令;1,表示数据; [size=10.0pt]voidOLED_WR_Byte(u8 dat,u8 cmd) [size=10.0pt]{ [size=10.0pt] u8i; [size=10.0pt] if(cmd) [size=10.0pt] OLED_DC_Set(); [size=10.0pt] else [size=10.0pt] OLED_DC_Clr(); [size=10.0pt] OLED_CS_Clr(); [size=10.0pt] for(i=0;i<8;i++) [size=10.0pt] { [size=10.0pt] OLED_SCLK_Clr(); [size=10.0pt] if(dat&0x80) [size=10.0pt] { [size=10.0pt] OLED_SDIN_Set(); [size=10.0pt] } [size=10.0pt]else [size=10.0pt] OLED_SDIN_Clr(); [size=10.0pt] OLED_SCLK_Set(); [size=10.0pt] dat<<=1; [size=10.0pt] } [size=10.0pt] OLED_CS_Set(); [size=10.0pt] OLED_DC_Set(); [size=10.0pt]} [size=10.0pt]#endif [size=10.0pt] voidOLED_Set_Pos(unsigned char x, unsigned char y) [size=10.0pt]{ [size=10.0pt] OLED_WR_Byte(0xb0+y,OLED_CMD); [size=10.0pt] OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD); [size=10.0pt] OLED_WR_Byte((x&0x0f)|0x01,OLED_CMD); [size=10.0pt]} [size=10.0pt]//[size=10.0pt]开启OLED显示 [size=10.0pt]voidOLED_Display_On(void) [size=10.0pt]{ [size=10.0pt] OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC[size=10.0pt]命令 [size=10.0pt] OLED_WR_Byte(0X14,OLED_CMD); //DCDC ON [size=10.0pt] OLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON [size=10.0pt]} [size=10.0pt]//[size=10.0pt]关闭OLED显示 [size=10.0pt]voidOLED_Display_Off(void) [size=10.0pt]{ [size=10.0pt] OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC[size=10.0pt]命令 [size=10.0pt] OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFF [size=10.0pt] OLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF [size=10.0pt]} [size=10.0pt]//[size=10.0pt]清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!! [size=10.0pt]voidOLED_Clear(void) [size=10.0pt]{ [size=10.0pt] u8i,n; [size=10.0pt] for(i=0;i<8;i++) [size=10.0pt] { [size=10.0pt] OLED_WR_Byte(0xb0+i,OLED_CMD); //[size=10.0pt]设置页地址(0~7) [size=10.0pt] OLED_WR_Byte(0x00,OLED_CMD); //[size=10.0pt]设置显示位置—列低地址 [size=10.0pt] OLED_WR_Byte(0x10,OLED_CMD); //[size=10.0pt]设置显示位置—列高地址 [size=10.0pt] for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA); [size=10.0pt] }//[size=10.0pt]更新显示 [size=10.0pt]} [size=10.0pt] [size=10.0pt] [size=10.0pt]//[size=10.0pt]在指定位置显示一个字符,包括部分字符 [size=10.0pt]//x:0~127 [size=10.0pt]//y:0~63 [size=10.0pt]//mode:0,[size=10.0pt]反白显示;1,正常显示 [size=10.0pt]//size:[size=10.0pt]选择字体 16/12 [size=10.0pt]voidOLED_ShowChar(u8 x,u8 y,u8 chr) [size=10.0pt]{ [size=10.0pt] unsignedchar c=0,i=0; [size=10.0pt] c=chr-'';//[size=10.0pt]得到偏移后的值 [size=10.0pt] if(x>Max_Column-1){x=0;y=y+2;} [size=10.0pt] if(SIZE==16) [size=10.0pt] { [size=10.0pt] OLED_Set_Pos(x,y); [size=10.0pt] for(i=0;i<8;i++) [size=10.0pt] OLED_WR_Byte(F8X16[c*16+i],OLED_DATA); [size=10.0pt] OLED_Set_Pos(x,y+1); [size=10.0pt] for(i=0;i<8;i++) [size=10.0pt] OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA); [size=10.0pt] } [size=10.0pt] else{ [size=10.0pt] OLED_Set_Pos(x,y+1); [size=10.0pt] for(i=0;i<6;i++) [size=10.0pt] OLED_WR_Byte(F6x8[c],OLED_DATA); [size=10.0pt] [size=10.0pt] } [size=10.0pt]} [size=10.0pt]//m^n[size=10.0pt]函数 [size=10.0pt]u32oled_pow(u8 m,u8 n) [size=10.0pt]{ [size=10.0pt] u32result=1; [size=10.0pt] while(n--)result*=m; [size=10.0pt] returnresult; [size=10.0pt]} [size=10.0pt]//[size=10.0pt]显示2个数字 [size=10.0pt]//x,y:[size=10.0pt]起点坐标 [size=10.0pt]//len:[size=10.0pt]数字的位数 [size=10.0pt]//size:[size=10.0pt]字体大小 [size=10.0pt]//mode:[size=10.0pt]模式 0,填充模式;1,叠加模式 [size=10.0pt]//num:[size=10.0pt]数值(0~4294967295); [size=10.0pt]voidOLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2) [size=10.0pt]{ [size=10.0pt] u8t,temp; [size=10.0pt] u8enshow=0; [size=10.0pt] for(t=0;t<len;t++) [size=10.0pt] { [size=10.0pt] temp=(num/oled_pow(10,len-t-1))%10; [size=10.0pt] if(enshow==0&&t<(len-1)) [size=10.0pt] { [size=10.0pt] if(temp==0) [size=10.0pt] { [size=10.0pt] OLED_ShowChar(x+(size2/2)*t,y,''); [size=10.0pt] continue; [size=10.0pt] }elseenshow=1; [size=10.0pt] [size=10.0pt] } [size=10.0pt] OLED_ShowChar(x+(size2/2)*t,y,temp+'0'); [size=10.0pt] } [size=10.0pt]} [size=10.0pt]//[size=10.0pt]显示一个字符号串 [size=10.0pt]voidOLED_ShowString(u8 x,u8 y,u8 *chr) [size=10.0pt]{ [size=10.0pt] unsignedchar i=0; [size=10.0pt] for(i = 0; i <= 20; i++){ [size=10.0pt] if(chr == '\0')break; [size=10.0pt] OLED_ShowChar(x,y, chr); [size=10.0pt] x+=8; [size=10.0pt] if(x>120){x=0;y+=2;} [size=10.0pt] } [size=10.0pt]} [size=10.0pt] [size=10.0pt]//[size=10.0pt]显示汉字 [size=10.0pt]voidOLED_ShowCHinese(u8 x,u8 y,u8 no) [size=10.0pt]{ [size=10.0pt] u8t,adder=0; [size=10.0pt] OLED_Set_Pos(x,y); [size=10.0pt] for(t=0;t<16;t++) [size=10.0pt] { [size=10.0pt] OLED_WR_Byte(Hzk[2*no][t],OLED_DATA); [size=10.0pt] adder+=1; [size=10.0pt] } [size=10.0pt] OLED_Set_Pos(x,y+1); [size=10.0pt] for(t=0;t<16;t++) [size=10.0pt] { [size=10.0pt] OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA); [size=10.0pt] adder+=1; [size=10.0pt] } [size=10.0pt]} [size=10.0pt]/***********[size=10.0pt]功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/ [size=10.0pt]voidOLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned chary1,unsigned char BMP[]) [size=10.0pt]{ [size=10.0pt] unsigned int j=0; [size=10.0pt] unsigned char x,y; [size=10.0pt] [size=10.0pt] if(y1%8==0) y=y1/8; [size=10.0pt] else y=y1/8+1; [size=10.0pt] for(y=y0;y<y1;y++) [size=10.0pt] { [size=10.0pt] OLED_Set_Pos(x0,y); [size=10.0pt] for(x=x0;x<x1;x++) [size=10.0pt] { [size=10.0pt] OLED_WR_Byte(BMP[j++],OLED_DATA); [size=10.0pt] } [size=10.0pt] } [size=10.0pt]} [size=10.0pt] [size=10.0pt] [size=10.0pt]//[size=10.0pt]初始化SSD1306 [size=10.0pt]voidOLED_Init(void) [size=10.0pt]{ [size=10.0pt] [size=10.0pt] [size=10.0pt] [size=10.0pt] OLED_RST_Set(); [size=10.0pt] delay_ms(100); [size=10.0pt] OLED_RST_Clr(); [size=10.0pt] delay_ms(100); [size=10.0pt] OLED_RST_Set(); [size=10.0pt] /* [size=10.0pt] OLED_WR_Byte(0xAE,OLED_CMD);//--turnoff oled panel [size=10.0pt] OLED_WR_Byte(0x00,OLED_CMD);//---setlow column address [size=10.0pt] OLED_WR_Byte(0x10,OLED_CMD);//---sethigh column address [size=10.0pt] OLED_WR_Byte(0x40,OLED_CMD);//--setstart line address Set Mapping RAM DisplayStart Line (0x00~0x3F) [size=10.0pt] OLED_WR_Byte(0x81,OLED_CMD);//--setcontrast control register [size=10.0pt] OLED_WR_Byte(0xCF,OLED_CMD);// Set SEG Output Current Brightness [size=10.0pt] OLED_WR_Byte(0xA1,OLED_CMD);//--SetSEG/Column Mapping 0xa0[size=10.0pt]左右反置 0xa1正常 [size=10.0pt] OLED_WR_Byte(0xC8,OLED_CMD);//SetCOM/Row Scan Direction 0xc0[size=10.0pt]上下反置 0xc8正常 [size=10.0pt] OLED_WR_Byte(0xA6,OLED_CMD);//--setnormal display [size=10.0pt] OLED_WR_Byte(0xA8,OLED_CMD);//--setmultiplex ratio(1 to 64) [size=10.0pt] OLED_WR_Byte(0x3f,OLED_CMD);//--1/64duty [size=10.0pt] OLED_WR_Byte(0xD3,OLED_CMD);//-setdisplay offset ShiftMapping RAM Counter (0x00~0x3F) [size=10.0pt] OLED_WR_Byte(0x00,OLED_CMD);//-notoffset [size=10.0pt] OLED_WR_Byte(0xd5,OLED_CMD);//--setdisplay clock divide ratio/oscillator frequency [size=10.0pt] OLED_WR_Byte(0x80,OLED_CMD);//--setdivide ratio, Set Clock as 100 Frames/Sec [size=10.0pt] OLED_WR_Byte(0xD9,OLED_CMD);//--setpre-charge period [size=10.0pt] OLED_WR_Byte(0xF1,OLED_CMD);//SetPre-Charge as 15 Clocks & Discharge as 1 Clock [size=10.0pt] OLED_WR_Byte(0xDA,OLED_CMD);//--setcom pins hardware configuration [size=10.0pt] OLED_WR_Byte(0x12,OLED_CMD); [size=10.0pt] OLED_WR_Byte(0xDB,OLED_CMD);//--setvcomh [size=10.0pt] OLED_WR_Byte(0x40,OLED_CMD);//SetVCOM Deselect Level [size=10.0pt] OLED_WR_Byte(0x20,OLED_CMD);//-SetPage Addressing Mode (0x00/0x01/0x02) [size=10.0pt] OLED_WR_Byte(0x02,OLED_CMD);// [size=10.0pt] OLED_WR_Byte(0x8D,OLED_CMD);//--setCharge Pump enable/disable [size=10.0pt] OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10)disable [size=10.0pt] OLED_WR_Byte(0xA4,OLED_CMD);//Disable Entire Display On (0xa4/0xa5) [size=10.0pt] OLED_WR_Byte(0xA6,OLED_CMD);//Disable Inverse Display On (0xa6/a7) [size=10.0pt] OLED_WR_Byte(0xAF,OLED_CMD);//--turnon oled panel [size=10.0pt] */ [size=10.0pt] [size=10.0pt] OLED_WR_Byte(0xAE,OLED_CMD);//--turnoff oled panel [size=10.0pt] OLED_WR_Byte(0x00,OLED_CMD);//---setlow column address [size=10.0pt] OLED_WR_Byte(0x10,OLED_CMD);//---sethigh column address [size=10.0pt] OLED_WR_Byte(0x40,OLED_CMD);//--setstart line address Set Mapping RAMDisplay Start Line (0x00~0x3F) [size=10.0pt] OLED_WR_Byte(0x81,OLED_CMD);//--setcontrast control register [size=10.0pt] OLED_WR_Byte(0xCF,OLED_CMD);// Set SEG Output Current Brightness [size=10.0pt] OLED_WR_Byte(0xA1,OLED_CMD);//--SetSEG/Column Mapping 0xa0[size=10.0pt]左右反置 0xa1正常 [size=10.0pt] OLED_WR_Byte(0xC8,OLED_CMD);//SetCOM/Row Scan Direction 0xc0[size=10.0pt]上下反置 0xc8正常 [size=10.0pt] OLED_WR_Byte(0xA6,OLED_CMD);//--setnormal display [size=10.0pt] OLED_WR_Byte(0xA8,OLED_CMD);//--setmultiplex ratio(1 to 64) [size=10.0pt] OLED_WR_Byte(0x3f,OLED_CMD);//--1/64duty [size=10.0pt] OLED_WR_Byte(0xD3,OLED_CMD);//-setdisplay offset ShiftMapping RAM Counter (0x00~0x3F) [size=10.0pt] OLED_WR_Byte(0x00,OLED_CMD);//-notoffset [size=10.0pt] OLED_WR_Byte(0xd5,OLED_CMD);//--setdisplay clock divide ratio/oscillator frequency [size=10.0pt] OLED_WR_Byte(0x80,OLED_CMD);//--setdivide ratio, Set Clock as 100 Frames/Sec [size=10.0pt] OLED_WR_Byte(0xD9,OLED_CMD);//--setpre-charge period [size=10.0pt] OLED_WR_Byte(0xF1,OLED_CMD);//SetPre-Charge as 15 Clocks & Discharge as 1 Clock [size=10.0pt] OLED_WR_Byte(0xDA,OLED_CMD);//--setcom pins hardware configuration [size=10.0pt] OLED_WR_Byte(0x12,OLED_CMD); [size=10.0pt] OLED_WR_Byte(0xDB,OLED_CMD);//--setvcomh [size=10.0pt] OLED_WR_Byte(0x40,OLED_CMD);//SetVCOM Deselect Level [size=10.0pt] OLED_WR_Byte(0x20,OLED_CMD);//-SetPage Addressing Mode (0x00/0x01/0x02) [size=10.0pt] OLED_WR_Byte(0x02,OLED_CMD);// [size=10.0pt] OLED_WR_Byte(0x8D,OLED_CMD);//--setCharge Pump enable/disable [size=10.0pt] OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10)disable [size=10.0pt] OLED_WR_Byte(0xA4,OLED_CMD);//Disable Entire Display On (0xa4/0xa5) [size=10.0pt] OLED_WR_Byte(0xA6,OLED_CMD);//Disable Inverse Display On (0xa6/a7) [size=10.0pt] OLED_WR_Byte(0xAF,OLED_CMD);//--turnon oled panel [size=10.0pt] [size=10.0pt] OLED_WR_Byte(0xAF,OLED_CMD);/*display ON*/ [size=10.0pt] OLED_Clear(); [size=10.0pt] OLED_Set_Pos(0,0); [size=10.0pt]} 如果哪位大大帮忙弄出来,感激不尽#5m |
|