#include <reg52.h>#include <intrins.h>#include <string.H>#define uchar unsigned char#define uint unsigned intunsigned char code SinWave[256] ={ //正弦波127 , 133 , 139 , 146 , 152 , 158 , 164 , 170,176, 181 , 187 , 192 , 198 , 203 , 208, 212 ,217 , 221 , 225 , 229 , 233, 236, 239, 242 , 244 , 247 , 249 , 250 , 252 , 253 , 253 , 254 ,254 , 254 , 253 , 253, 252 , 250 , 249 , 247 ,244, 242 , 239, 236 , 233 , 229 , 225 , 221 ,217 , 212 , 208 , 203 , 198 , 192 , 187 , 181 ,176 , 170 , 164 , 158 , 152 , 146 , 139 , 133 ,127 , 121 , 115 , 108 , 102 , 96 , 90 , 84 ,78 , 73 , 67 , 62 , 56 , 51 , 46 , 42 ,37 , 33, 29 , 25 , 21 , 18 , 15 , 12 , 10 , 7 , 5 , 4 , 2 , 1 , 1 , 0 ,0 , 0 , 1 , 1 , 2 , 4 , 5 , 7 ,10 , 12 , 15 , 18 , 21 , 25 , 29 , 33 ,37 , 42 , 46 , 51 , 56 , 62 , 67 , 73 ,78 , 84 , 90 , 96 , 102 , 108 , 115 , 121 ,} ;unsigned char code SawWave[256] = { //锯齿波0, 2, 4, 6, 8, 10, 12, 14,16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100,102,104,106,108,110, 112,114,116,118,120,122,124,126, 128 ,130,132,134,136,138,140,142, 144 ,146,148,150,152,154,156,158, 160 ,162,164,166,168,170,172,174, 176 ,178,180,182,184,186,188,190, 192,194 ,196,198,200,202,204,206, 208,210 ,212,214,216,218,220,222, 224,226 ,228,230,232,234,236,238, 240,242 ,244,246,248,250,252,254, };unsigned char code TriWave[256]= { //三角波0 , 4 , 8, 12 , 16 , 20 , 24 , 28 , 32 , 36 , 40, 44 , 48 , 52 , 56 , 60 ,64 , 68 , 72 , 76 , 80 , 84 , 88 , 92 , 96 ,100 , 104 , 108 , 112 , 116 , 120 , 124 ,128 ,132 , 136, 140 , 144 , 148 , 152 , 156 , 160 , 164 , 168, 172 , 176 , 180, 184 , 188 ,192 , 196 , 200, 204, 208 , 212 , 216 , 220 , 224 , 228 , 232, 236 , 240 , 244 , 248 , 252 ,255 , 251 , 247 , 243, 239 , 235 , 231 , 227 ,223 , 219 , 215, 211 , 207 , 203 , 199 , 195 ,191 , 187 , 183, 179, 175 , 171 , 167 , 163 , 159 , 155 , 151, 147, 143 , 139 , 135 , 131 ,127 , 123 , 119, 115, 111 ,107 , 103 , 99 ,95 , 91 , 87 , 83 , 79 , 75 , 71 , 67 ,63 , 59 , 55 , 51 , 47 ,43 , 39 , 35 ,31 , 27, 23 , 19 , 15 , 11 , 7 , 3 ,};unsigned char code SquWave[256] = { //方波255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,};unsigned char code TraWave[256] = {//梯形波0 , 6 , 12 , 18 , 24 , 30 , 36 , 42 , 48 , 54 , 60 , 66 , 72 , 78 , 84 , 90 ,96 , 102 , 108, 114 , 120, 126 , 132 , 138 , 144 , 150 , 156, 162 , 168 , 174 , 180 , 186 ,192 , 198 , 204 , 210 , 216 , 222 , 228 , 234 , 240 , 246 , 252 , 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255 , 249 , 243 , 237 , 231 , 225 , 219 , 213, 207 , 201 , 195 ,189 , 183 , 177 , 171 , 165 , 159 , 153 , 147 , 141, 135 , 129 , 123 , 117 , 111 , 105 , 99 , 93 , 87 , 81 , 75 , 69 , 63 , 57 , 51 , 45 , 39 ,33 , 27 , 21, 15 , 9 , 3 ,};unsigned char code *pWave; //波表指针unsigned char T0RH = 0; //T0重载值的高字节unsigned char T0RL = 0; //T0重载值的低字节unsigned char T1RH = 1; //T1重载值的高字节unsigned char T1RL = 1; //T1重载值的低字节unsigned char f;//频率unsigned char flag_t=1,flag_pcf=1;int fre=10,amp,i=0,j=1,m_delay=0,spacing=20,t=200,wave_cnt=72;uchar state=0;void SetWaveFreq(unsigned char freq,unsigned char spacing);/////////////////////串口通讯uchar fig,b,qq;uchar fasong[6]={0xAA,0x55,0x01,0x00,0x55,0xAA}; //使用strcmp和strcpy需要定义好数组长度char jieshou[3];//接收字符串存放处 8是字符串位 可根据实际更改 初始数组有\0空字符//此小程序就是串口助手发送8位字符串数据给单片机 单片机接收到与固定字符串对比,如果对就将接受到的数据再发送个串口助手,此小程序有利于帮助理解串口接收 数据对比 数据发送的一个过程,最基础的 也是自己琢磨出来的 大家多发表,大师多提意见,这个程序还有一个小BUG 但是不影响使用 就是上位机发送数据是 AA0101BB能正常接收 但是如果上位机发送的是 AA0101BBAA 这样的数据 之后再发送正常数据 单片机第一次接收不到,所以要对上位机的协议进行限制void Urat_init(){PCON &= 0x7F; //波特率不倍速 SMOD=0SCON = 0x50; //方式1,8位数据,可变波特率,接收允许T2CON = 0x34; RCAP2H = 0xFF; RCAP2L = 0xDC; TH2 = 0xFF; TL2 = 0xDC; EA=1; //总中断打开,采用查询法时不用打开中断 ES = 1; //串口中断开关,采用查询法时不用打开中断}///////////lcd1602//#define out P0sfr T2MOD=0XC9; //寄存器T2MOD定义sbit LCD_RS=P2^2;sbit LCD_RW=P2^1;sbit LCD_E=P2^0;sbit LED=P2^4;sbit KEY=P3;char hour=0,minute=10,second=0;//时间变量:时、分、秒char stre=0,mod=1;uint loop=1,n=0;uchar T0_flag=0;void Delay_lcd(unsigned int xms){//延时函数unsigned char i, j;while(xms--){i = 2;j = 239;do{while (--j);} while (--i);}}void LCD_WriteCmd(uchar Command){//写命令函数LCD_RS=0;LCD_RW=0;P0=Command;LCD_E=1;Delay_lcd(1);LCD_E=0;Delay_lcd(1);}void LCD_WriteData(uchar Data){//写数据函数LCD_RS=1;LCD_RW=0;P0=Data;LCD_E=1;Delay_lcd(1);LCD_E=0;Delay_lcd(1);}void LCD_Init(void){//初始化LCD1602LCD_WriteCmd(0x38);LCD_WriteCmd(0x0C);LCD_WriteCmd(0x06);LCD_WriteCmd(0x01);}void LCD_SetCursor(uchar Line,uchar Column){//选择显示的行和列:参数一代表行,参数二代表列LCD_WriteCmd(Line==1?0x80+(Column-1):0xC0+(Column-1));}void LCD_ShowString(uchar Line,uchar Column,char *String){//选择要显示的字字符串,参数一代表行,参数二代表列,参数三要传一个字符串进来,或者字符型的指针unsigned char i;LCD_SetCursor(Line,Column);for(i=0;String[i]!='\0';i++)LCD_WriteData(String[i]);}void LCD_ShowTime(char h,char m,char s){//在lcd1602上面显示时间 ,用定时器1 LCD_ShowString(1,1,"Time:");LCD_SetCursor(1,6); LCD_WriteData(h/10+0x30);LCD_WriteData(h%10+0x30);LCD_WriteData(0x3a);LCD_WriteData(m/10+0x30);LCD_WriteData(m%10+0x30);LCD_WriteData(0x3a);LCD_WriteData(s/10+0x30);LCD_WriteData(s%10+0x30); LCD_ShowString(2,1,"Modol:"); LCD_SetCursor(2,7); LCD_WriteData(mod/10+0x30); LCD_WriteData(mod%10+0x30); LCD_ShowString(2,10,"Stre:"); LCD_WriteData(stre/10+0x30); LCD_WriteData(stre%10+0x30); }void TIM2Inital(void){/* T2MOD = 0; //---- --00 初始化模式寄存器 默认向上计数T2CON = 0; //0000 0000 初始化控制寄存器 一个中断源,16位自动重装模式TL2 = 0x00; //设置定时初值TH2 = 0x4C; //设置定时初值RCAP2L = 0x00; //设置定时重载值RCAP2H = 0x4C; //设置定时重载值TR2 = 0; //定时器2关闭计时//IE=0XA8; //0xa0 1010 0000 打开全局中断,定时器2中断 这个命令会阻碍其他计时器启动 0xa8 将ET1=1允许T1执行中断程序ET1=1; //计时器1 0关断,1打开/////////////////////////////RCAP2H = (65536-60000)/256;//晶振12M 60ms 16bit 自动重载RCAP2L = (65536-60000)%256;ET2=1; //打开定时器中断EA=1; //打开总中断TR2=0; //打开定时器开关 */TMOD &= 0xF0; //设置定时器模式TMOD |= 0x01; //设置定时器模式TH0=(65535-50000)/256;TL0=(65535-50000)%256;TF0 = 0; //清除TF0标志ET0=1; //打开小开关EA=1; //打开总开关 // TR0=1;//打开定时器 }////////////////////////////////lcd160_end//extern void KeyScan();//extern void KeyDriver();extern void I2CStart();extern void I2CStop();extern bit I2CWrite(unsigned char dat);void delay(unsigned int z) //延迟函数{ unsigned int x,y; for(x=z;x>0;x--) for(y=125;y>0;y--) ;}void delay_k(uint xms) //延时子函数{uint i,j;for(i=xms;i>0;i--)for(j=110;j>0;j--);}/*程序控制*/void models(unsigned char dat){switch(dat){case 1:wave_cnt=128; //各种波的波形范围,超出变形if(i<5){i++;pWave = SquWave; //默认矩形波fre=25; //fre和spacing对周期大小微调,单一调节变化不大spacing=12;t=100;//t调节间距,也就是对T1 中断延迟,来增加间距 SetWaveFreq(fre,spacing); //默认频率 10HzLED=0;m_delay=100; // SetWaveFreq调节速率}else if(i>=5 & i<10){ i++;LED=1;t=200;fre=10;spacing=20; SetWaveFreq(fre,spacing); //默认频率 10Hzm_delay=100;}else {i=0;fre=20;spacing=20;t=100;LED=0;m_delay=100; }break; case 2:wave_cnt=128;if(i<5){i++;pWave = TraWave; //默认正弦波fre=10;spacing=12;t=10; SetWaveFreq(fre,spacing); //默认频率 10HzLED=0;}else if(i>=5 & i<10){ i++;LED=1;t=200;fre=10;spacing=20; SetWaveFreq(fre,spacing); //默认频率 10Hz}else {i=0;fre=20;spacing=20;t=100;LED=0;}break;case 3:wave_cnt=64;if(i<5){i++;pWave = SinWave; //默认正弦波fre=25;spacing=12;t=100; SetWaveFreq(fre,spacing); //默认频率 10HzLED=0;m_delay=100;}else if(i>=5 & i<10){ i++;LED=1;t=200;fre=10;spacing=20; SetWaveFreq(fre,spacing); //默认频率 10Hzm_delay=100;}else {i=0;fre=20;spacing=20;t=100;LED=0;m_delay=100; }break;case 4:wave_cnt=128;if(i<5){i++;pWave = TriWave; //默认正弦波fre=25;spacing=12;t=100; SetWaveFreq(fre,spacing); //默认频率 10HzLED=0;m_delay=100;}else if(i>=5 & i<10){ i++;LED=1;t=200;fre=10;spacing=20; SetWaveFreq(fre,spacing); //默认频率 10Hzm_delay=100;}else {i=0;fre=20;spacing=20;t=100;LED=0;m_delay=100; }break;default:wave_cnt=256;if(i<5){i++;pWave = SawWave; //默认正弦波fre=35;spacing=12;t=10; SetWaveFreq(fre,spacing); //默认频率 10HzLED=0;m_delay=10;}else if(i>=5 & i<10){ i++;LED=1;t=20;fre=10;spacing=20; SetWaveFreq(fre,spacing); //默认频率 10Hzm_delay=10;}else {i=0;fre=5;spacing=20;t=10;LED=0;m_delay=10; }break;break;}}////////////////////////串口void urat_code(){if(strcmp(jieshou,"00")==0)//调节时间+{TR0=0;TR1=0;//0xaa,0x55,0x02,0xf3,0x00,0xf5fasong[2]=0x03;//这里给某个十六进制赋值//strcpy(fasong,'0xaa''0x55'});for(i=0;i<6;i++)//注意strcpy字符不能溢出{SBUF=fasong[i];while(!TI);TI=0;}fig=0;if(minute<30){second=0;if(minute>20){minute=30;}else{minute=minute+10;}}else{second=0;minute=10;}if(state==1){TR0=1;TR1=1;}}if(strcmp(jieshou,"01")==0)//时间-{TR0=0;TR1=0;strcpy(fasong,"AA000255");for(i=0;i<8;i++)//注意strcpy字符不能溢出{SBUF=fasong[i];while(!TI);TI=0;}fig=0;if(minute>0){second=0;if(minute<10){minute=0;} else{minute=minute-10;}}else{second=0;minute=0;}if(state==1){TR0=1;TR1=1;}}if(strcmp(jieshou,"02")==0)//功能模式+{TR0=0;TR1=0;strcpy(fasong,"AA010255");for(i=0;i<8;i++)//注意strcpy字符不能溢出{SBUF=fasong[i];while(!TI);TI=0;}fig=0;if(mod<5){mod++;}else{mod=1;}if(state==1){TR0=1;TR1=1;}}if(strcmp(jieshou,"03")==0)//功能模式-{TR0=0;TR1=0;strcpy(fasong,"AA010355");for(i=0;i<8;i++)//注意strcpy字符不能溢出{SBUF=fasong[i];while(!TI);TI=0;}fig=0;if(mod>0){mod--;}else{mod=1;}if(state==1){TR0=1;TR1=1;}}if(strcmp(jieshou,"04")==0)//强度+{TR0=0;TR1=0;strcpy(fasong,"AA010155");for(i=0;i<8;i++)//注意strcpy字符不能溢出{SBUF=fasong[i];while(!TI);TI=0;}fig=0;if(stre<10){stre++;}else{stre=1;}if(state==1){TR0=1;TR1=1;}}if(strcmp(jieshou,"05")==0)//强度-{TR0=0;TR1=0;strcpy(fasong,"AA000555");for(i=0;i<8;i++)//注意strcpy字符不能溢出{SBUF=fasong[i];while(!TI);TI=0;}fig=0;ES=1;if(stre>0){stre--;}else{stre=1;}if(state==1){TR0=1;TR1=1;}}if(strcmp(jieshou,"06")==0)//启动{strcpy(fasong,"AA000655");for(i=0;i<8;i++)//注意strcpy字符不能溢出{SBUF=fasong[i];while(!TI);TI=0;}fig=0;state=1;//启动标识TR1=0;TR0=0;models(mod);TR1=1;TR0=1;}if(strcmp(jieshou,"07")==0)//停止{strcpy(fasong,"AA000755");for(i=0;i<8;i++)//注意strcpy字符不能溢出{SBUF=fasong[i];while(!TI);TI=0;}fig=0;minute=0;second=0;stre=1;state=0;//启动标识TR1=0;TR0=0;}}void senddat(){unsigned char dat[6]={0xaa,0x55,0x02,0xf3,0x00,0xf5};unsigned char dat2[6]={0xaa,0x55,0x02,0xf3,0x00,0xf5};unsigned char i;for(i=0;i<6;i++){TI=0;SBUF=dat[i];while(!TI);TI=0;}for(i=0;i<6;i++){TI=0;SBUF=dat2[i];while(!TI);TI=0;}}/////////////////////////////void main(){ Urat_init();LCD_Init(); TIM2Inital();while (1){LCD_ShowTime(hour,minute,second); models(mod);if(fig==1){urat_code();}}}//////////////lcd 倒计时void TIM2(void) interrupt 1//interrupt 5//定时器2中断{//定时器0中断函数//T2 TF2=0; //!!!注意!!! 定时器2必须由软件对溢出标志位清零,硬件不能清零,这里与定时器0和定时器1不同!!!T0_flag++;if(T0_flag==20){ //这里数微调时间shour=0;T0_flag=0; if(minute>0){if(second>0){second--;}else{minute--;second=59;}} else{minute=0;second=0;hour=0;}}}/////////////////////end lcd倒计时/* 设置DAC输出值,val-设定值 */void SetDACOut(unsigned char val){I2CStart();if (!I2CWrite(0x48<<1)){ //寻址 PCF8591,如未应答,则停止操作并返回I2CStop();return;}I2CWrite(0x40); //写入控制字节I2CWrite(val); //写入 DA 值I2CStop();}/*改变频率*/void SetWaveFreq(unsigned char freq,unsigned char spacing){unsigned long tmp;tmp = (6059200/spacing) / (freq*16); //定时器计数频率,是波形频率的 32 倍tmp = 65536 - tmp; //计算定时器重载值tmp = tmp + 33; //修正中断响应延时造成的误差T1RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节T1RL = (unsigned char)tmp;TMOD &= 0x0F; //清零 T1 的控制位TMOD |= 0x10; //配置 T1 为模式 1TH1 = T1RH; //加载 T1 重载值TL1 = T1RL;ET1 = 1; //使能 T1 中断PT1 = 1; //设置为高优先级delay(m_delay);//调节速率//TR1 = 1; //启动 T1}/* T1中断服务函数,执行波形输出 */void InterruptTimer1() interrupt 3{static unsigned char i = 0;TH1 = T1RH; //重新加载重载值TL1 = T1RL;//循环输出波表中的数据SetDACOut(pWave[i]);i++;if (i >= wave_cnt){i = 0;delay_k(t); //间距 }}///串口中断4void URAT_ZD()interrupt 4{EA = 0;if(RI == 1) //当硬件接收到一个数据时,RI会置位{RI=0;jieshou[b]=SBUF; //将串口数据取走,存放到数组当中b++;if(b==2){b=0;fig=1;//代表sbuf接收完毕}}EA = 1;}urat_code()方法里给其中十六进制某一个十六进制进行重新赋值,其他校验码其实不用每次都重新赋值的。如果都要覆盖,那目前我也没有太简单一句话就可以赋值,但我觉得我这个方法简洁实用。
uchar你之前定义过吗?你这是对数组赋值,而数组的赋值只有二种方法,一种是初始化赋值,它可以对数组整体赋值,即,你可以用ucharfrist[5]={xxxxx};第二种就是在程序执行中赋值,即,没有经过初始化赋值;那么此时对它的赋值只能是逐个赋值,而不能像初始化赋值那样对整体来赋值了。你先定义了数组ucharfirst[5];即没用有初始化赋值,所以是程序执行中的赋值,故只能逐个对它赋值了。即只能用first[0]=a,first[1]=b,这样来赋值了。明白了吧,呵呵。
首先要弄清楚io口的赋值!!使用并行输数据只能八位。所有,oxfffe要取出高八位和低八位!!因为不存在取单独某位的问题,所有可以使用简单的移位语句p1=(oxfffe<<8);//左移八位,得p1=oxfep2=(oxfffe>>8);//右移8位,得p2=oxff你这个程序的错误在于,p1口使用并行方法输送数据只能一次传输8位,而oxfffe位十六位,溢出错误!!