当前位置:网站首页 > API设计与开发 > 正文

单片机设计原理图和仿真图一样吗(单片机程序和仿真图)



 1 #include <reg52.h>  2 #include <intrins.h>  3  4 #define uchar unsigned char // 以后unsigned char就可以用uchar代替  5 #define uint unsigned int // 以后unsigned int 就可以用uint 代替  6  7 sfr ISP_DATA = 0xe2; // 数据寄存器  8 sfr ISP_ADDRH = 0xe3; // 地址寄存器高八位  9 sfr ISP_ADDRL = 0xe4; // 地址寄存器低八位  10 sfr ISP_CMD = 0xe5; // 命令寄存器  11 sfr ISP_TRIG = 0xe6; // 命令触发寄存器  12 sfr ISP_CONTR = 0xe7; // 命令寄存器  13  14 sbit LcdRs_P = P1^1; // 1602液晶的RS管脚   15 sbit LcdRw_P = P1^2; // 1602液晶的RW管脚   16 sbit LcdEn_P = P1^3; // 1602液晶的EN管脚  17  18 sbit Trig1_P = P3^2; // 超声波模块1的Trig管脚  19 sbit Echo1_P = P3^3; // 超声波模块1的Echo管脚  20  21 sbit KeySet_P = P2^2; // 设置按键的管脚  22 sbit KeyDown_P = P2^1; // 减按键的管脚  23 sbit KeyUp_P = P2^0; // 加按键的管脚  24  25 sbit Buzzer_P = P2^3; // 蜂鸣器的管脚  26 sbit Led1_P = P3^4; // 传感器1报警灯  27  28 uint gAlarm; // 报警距离变量  29  30  31  32 /***/  33 // 单片机内部EEPROM不使能  34 /***/  35 void ISP_Disable()  36 {  37 ISP_CONTR = 0;  38 ISP_ADDRH = 0;  39 ISP_ADDRL = 0;  40 }  41  42  43 /***/  44 // 从单片机内部EEPROM读一个字节,从0x2000地址开始  45 /***/  46 unsigned char EEPROM_Read(unsigned int add)  47 {  48 ISP_DATA = 0x00;  49 ISP_CONTR = 0x83;  50 ISP_CMD = 0x01;  51 ISP_ADDRH = (unsigned char)(add>>8);  52 ISP_ADDRL = (unsigned char)(add&0xff);  53 // 对STC89C51系列来说,每次要写入0x46,再写入0xB9,ISP/IAP才会生效  54 ISP_TRIG = 0x46;  55 ISP_TRIG = 0xB9;  56  _nop_();  57  ISP_Disable();  58 return (ISP_DATA);  59 }  60  61  62 /***/  63 // 往单片机内部EEPROM写一个字节,从0x2000地址开始  64 /***/  65 void EEPROM_Write(unsigned int add,unsigned char ch)  66 {  67 ISP_CONTR = 0x83;  68 ISP_CMD = 0x02;  69 ISP_ADDRH = (unsigned char)(add>>8);  70 ISP_ADDRL = (unsigned char)(add&0xff);  71 ISP_DATA = ch;  72 ISP_TRIG = 0x46;  73 ISP_TRIG = 0xB9;  74  _nop_();  75  ISP_Disable();  76 }  77  78  79 /***/  80 // 擦除单片机内部EEPROM的一个扇区  81 // 写8个扇区中随便一个的地址,便擦除该扇区,写入前要先擦除  82 /***/  83 void Sector_Erase(unsigned int add)  84 {  85 ISP_CONTR = 0x83;  86 ISP_CMD = 0x03;  87 ISP_ADDRH = (unsigned char)(add>>8);  88 ISP_ADDRL = (unsigned char)(add&0xff);  89 ISP_TRIG = 0x46;  90 ISP_TRIG = 0xB9;  91  _nop_();  92  ISP_Disable();  93 }  94  95  96  97 /***/  98 // 毫秒级的延时函数,time是要延时的毫秒数  99 /***/ 100 void DelayMs(uint time) 101 { 102 uint i,j; 103 for(i=0;i<time;i++) 104 for(j=0;j<112;j++); 105 } 106 107 108 /***/ 109 // 1602液晶写命令函数,cmd就是要写入的命令 110 /***/ 111 void LcdWriteCmd(uchar cmd) 112 { 113 LcdRs_P = 0; 114 LcdRw_P = 0; 115 LcdEn_P = 0; 116 P0=cmd; 117 DelayMs(2); 118 LcdEn_P = 1; 119 DelayMs(2); 120 LcdEn_P = 0; 121 } 122 123 124 /***/ 125 // 1602液晶写数据函数,dat就是要写入的数据 126 /***/ 127 void LcdWriteData(uchar dat) 128 { 129 LcdRs_P = 1; 130 LcdRw_P = 0; 131 LcdEn_P = 0; 132 P0=dat; 133 DelayMs(2); 134 LcdEn_P = 1; 135 DelayMs(2); 136 LcdEn_P = 0; 137 } 138 139 140 /***/ 141 // 液晶光标定位函数 142 /***/ 143 void LcdGotoXY(uchar line,uchar column) 144 { 145 // 第一行 146 if(line==0) 147 LcdWriteCmd(0x80+column); 148 // 第二行 149 if(line==1) 150 LcdWriteCmd(0x80+0x40+column); 151 } 152 153 154 155 /***/ 156 // 液晶输出字符串函数 157 /***/ 158 void LcdPrintStr(uchar *str) 159 { 160 while(*str!='0') 161 LcdWriteData(*str++); 162 } 163 164 165 /***/ 166 // 液晶输出数字 167 /***/ 168 void LcdPrintNum(uint num) 169 { 170 LcdWriteData(num/100+0x30); // 百位 171 LcdWriteData(num%100/10+0x30); // 十位 172 LcdWriteData(num%10+0x30); // 个位 173 } 174 175 176 /***/ 177 // 1602液晶功能初始化 178 /***/ 179 void LcdInit() 180 { 181 LcdWriteCmd(0x38); // 16*2显示,5*7点阵,8位数据口 182 LcdWriteCmd(0x0C); // 开显示,不显示光标 183 LcdWriteCmd(0x06); // 地址加1,当写入数据后光标右移 184 LcdWriteCmd(0x01); // 清屏 185 } 186 187 188 189 /***/ 190 // 1602液晶显示内容初始化 191 /***/ 192 void LcdShowInit() 193 { 194 LcdGotoXY(0,0); // 定位到第0行第0列 195 LcdPrintStr("D: cm "); // 第0行显示"D: " 196 } 197 198 199 /***/ 200 // 计算传感器1测量到的距离 201 /***/ 202 203 uint GetDistance1(void) 204 { 205 uint ss; // 用于记录测得的距离 206 207 TH0=0; 208 TL0=0; 209 210 Trig1_P=1; // 给超声波模块1一个开始脉冲 211 DelayMs(1); 212 Trig1_P=0; 213 214 while(!Echo1_P); // 等待超声波模块1的返回脉冲 215 TR0=1; // 启动定时器,开始计时 216 while(Echo1_P); // 等待超声波模块1的返回脉冲结束 217 TR0=0; // 停止定时器,停止计时 218 219 ss=((TH0*256+TL0)*0.034)/2; // 距离cm=(时间us * 速度cm/us)/2 220 return ss; 221 } 222 223 /***/ 224 // 按键扫描 225 /***/ 226 void KeyScanf() 227 { 228 if(KeySet_P==0) // 判断是否有按键按下 229  { 230 LcdGotoXY(0,0); // 光标定位 231 LcdPrintStr(" Alarm Set "); // 第0行显示“ Alarm Set ” 232 LcdGotoXY(1,0); // 光标定位 233 LcdPrintStr(" alarm= cm "); // 第1行显示“ alarm= cm ” 234 LcdGotoXY(1,8); // 光标定位 235 LcdPrintNum(gAlarm); // 显示当前的报警值 236 237 DelayMs(10); // 消除按键按下的抖动 238 while(!KeySet_P); // 等待按键释放 239 DelayMs(10); // 消除按键松开的抖动  240 241 while(1) 242  { 243 /* 报警值减的处理 */ 244 if(KeyDown_P==0) 245  { 246 if(gAlarm>2) // 报警值大于2才能减1 247 gAlarm--; // 报警值减1 248 LcdGotoXY(1,8); // 光标定位 249 LcdPrintNum(gAlarm); // 刷新修改后的报警值 250 DelayMs(300); // 延时 251  } 252 253 /* 报警值加的处理 */ 254 if(KeyUp_P==0) 255  { 256 if(gAlarm<400) // 报警值小于400才能加1 257 gAlarm++; // 报警值加1 258 LcdGotoXY(1,8); // 光标定位 259 LcdPrintNum(gAlarm); // 刷新修改后的报警值 260 DelayMs(300); // 延时 261  } 262 263 /* 退出报警值设置 */ 264 if(KeySet_P==0) 265  { 266 break; // 退出while循环 267  } 268  } 269 270 LcdShowInit(); // 液晶恢复测量到测量界面 271 DelayMs(10); // 消除按键按下的抖动 272 while(!KeySet_P); // 等待按键释放 273 DelayMs(10); // 消除按键松开的抖动  274 275 Sector_Erase(0x2000); // 保存报警距离 276 EEPROM_Write(0x2000,gAlarm/100); 277 EEPROM_Write(0x2001,gAlarm%100); 278  } 279 } 280 281 282 /***/ 283 // 传感器1报警判断 284 /***/ 285 void AlarmJudge1(uint ss) 286 { 287 288 if(ss<gAlarm) // LED灯判断 289  { 290 Led1_P=0; 291 Buzzer_P=1; 292 DelayMs(10); 293 Buzzer_P=0; 294 DelayMs(10); 295  } 296 else 297  { 298 Led1_P=1; 299 Buzzer_P=0; 300  } 301 302 303 } 304 305 /***/ 306 // 报警值初始化 307 /***/ 308 void AlarmInit() 309 { 310 gAlarm=EEPROM_Read(0x2000)*100+EEPROM_Read(0x2001); // 从EEPROM读取报警值 311 312 if((gAlarm==0)||(gAlarm>400)) // 如果读取到的报警值异常(等于0或大于400则认为异常) 313  { 314 gAlarm=15; // 重新赋值报警值为15 315  } 316 } 317 318 319 /***/ 320 // 主函数 321 /***/ 322 void main() 323 { 324 uchar i; // 循环变量 325 uint dist; // 保存测量结果 326 327 LcdInit(); // 液晶功能初始化 328 LcdShowInit(); // 液晶显示内容初始化 329 AlarmInit(); // 报警值初始化 330 331 TMOD = 0x01; // 选择定时器0,并且确定是工作方式1(为了超声波模块测量距离计时用的) 332 333 Trig1_P=0; // 初始化触发引脚为低电平 334 335 while(1) 336  { 337 /*传感器1*/ 338 dist=GetDistance1(); // 读取超声波模块1测量到的距离 339 LcdGotoXY(0,7); // 光标定位 340 LcdPrintNum(dist); // 显示传感器1测量到的距离 341 AlarmJudge1(dist); // 判断传感器1的测量距离是否需要报警 342 343 /*延时并扫描按键*/ 344 for(i=0;i<15;i++) 345  { 346  KeyScanf(); 347 DelayMs(10); 348  } 349 350 351  } 352 }
到此这篇单片机设计原理图和仿真图一样吗(单片机程序和仿真图)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • can通讯接口设计(can 通讯)2025-01-18 23:18:06
  • 单片机设计课程(单片机设计课程心得体会)2025-01-18 23:18:06
  • 51单片机设计篮球计时计分器(基于51单片机篮球计时计分器)2025-01-18 23:18:06
  • tp9950电路设计(tpdt962pc791电路图)2025-01-18 23:18:06
  • 操作系统 课程(操作系统课程设计报告)2025-01-18 23:18:06
  • 单片机设计与开发是什么(单片机设计与开发项目)2025-01-18 23:18:06
  • 字体标志设计(字体标志设计的案例)2025-01-18 23:18:06
  • 战斗系统设计(战斗系统设定)2025-01-18 23:18:06
  • 单片机程序示例(单片机程序示例设计)2025-01-18 23:18:06
  • 安装win32api(安装win3.2支持FAT16)2025-01-18 23:18:06
  • 全屏图片