活动介绍

c程序运行结果不稳定#include <reg52.h> #include <intrins.h> #include <math.h> #include <stdio.h> #define uchar unsigned char #define uint unsigned int bit flag_KEY=0; //按键松开标志位 uint Time1ms=0; //LCD定义 #define LCD_DB P0 sbit LCD_RS=P2^0; sbit LCD_RW=P2^1; sbit LCD_E=P2^2; //按键定义 sbit K1=P3^5; sbit K2=P3^6; //蜂鸣器定义 sbit FMQ=P1^6; //检测速度 uint Speed=0; uint Count=0; uint Alarm=900; /*------------------------------------- 函数申明 ---------------------------------------*/ void LCD_init(void); //初始化函数 void LCD_write_command(uchar command); //写指令函数 void LCD_write_data(uchar dat); //写数据函数 void LCD_disp_char(uchar x,uchar y,uchar dat);//在某个屏幕位置上显示一个字符,X(0-15),y(1-2) void LCD_disp_str(uchar x,uchar y,uchar *str); //LCD1602显示字符串函数 void delay_n10us(uint n); //延时函数 /*------------------------------------------------ 外部中断0程序 ------------------------------------------------*/ void INT() interrupt 0 { Count++; } /*------------------------------------------ 定时器0中断处理 --------------------------------------------*/ void tim0_isr(void) interrupt 1 using 1 { TH0=0XFC; TL0=0X66; Time1ms++; } /*------------------------------------- 定时器初始化 ---------------------------------------*/ void TIM0init(void) { TMOD=0x21; TH0=0xDC; //定时0.1ms TL0=0x00; ET0=1; TR0=1; EA=1; SCON = 0x50; TH1 = 0xFD; TL1 = TH1; PCON = 0x00; //ES = 1; //串口的中断开关 TI = 1; TR1 = 1; } /*------------------------------------- LCD1602子程序 ---------------------------------------*/ void LCD_init(void) { delay_n10us(10); LCD_write_command(0x38);//设置8位格式,2行,5x7 delay_n10us(10); LCD_write_command(0x0c);//开显示,关光标,不闪烁 delay_n10us(10); LCD_write_command(0x06);//设定输入方式,增量不移位 delay_n10us(10); LCD_write_command(0x01);//清除屏幕显示 delay_n10us(100); //延时清屏,延时函数,延时约n个10us } void LCD_write_command(uchar dat) { delay_n10us(10); LCD_RS=0; //指令 LCD_RW=0; //写入 LCD_E=1; //允许 LCD_DB=dat; delay_n10us(10); //实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。 LCD_E=0; delay_n10us(10); //实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。 } void LCD_write_data(uchar dat) { delay_n10us(10); LCD_RS=1; //数据 LCD_RW=0; //写入 LCD_E=1; //允许 LCD_DB=dat; delay_n10us(10); LCD_E=0; delay_n10us(10); } void LCD_disp_char(uchar x,uchar y,uchar dat) { uchar address; if(y==1) address=0x80+x; else address=0xc0+x; LCD_write_command(address); LCD_write_data(dat); } void LCD_disp_str(uchar x,uchar y,uchar *str) { uchar address; if(y==1) address=0x80+x; else address=0xc0+x; LCD_write_command(address); while(*str!='\0') { LCD_write_data(*str); str++; } } void delay_n10us(uint n) //延时 { uint i; for(i=n;i>0;i--) { nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); } } /*------------------------------------- 按键扫描 ---------------------------------------*/ void keyscan() { if(K1==0)//设定报警速度+ { if(flag_KEY==1) //按键只响应1次 { flag_KEY=0; if(Alarm<950) Alarm=Alarm+50; } } if(K2==0)//设定报警速度- { if(flag_KEY==1) //按键只响应1次 { flag_KEY=0; if(Alarm>0) Alarm=Alarm-50; } } //全部按键松开 if(K1&&K2) { flag_KEY=1; } } /*------------------------------------- 测速程序 ---------------------------------------*/ void Check() { //-----定时1秒-------- if(Time1ms>=1000) { Time1ms=0; Speed=Count*20; Count=0; if(Speed>=Alarm) { FMQ=0; } else { FMQ=1; } } } /*------------------------------------- LCD显示 ---------------------------------------*/ void DisPlay() { LCD_disp_char(2,1,Speed/1000+'0'); LCD_disp_char(3,1,Speed/100%10+'0'); LCD_disp_char(4,1,Speed/10%10+'0'); LCD_disp_char(5,1,Speed%10+'0'); LCD_disp_char(13,1,Alarm/100+'0');//显示报警速度的 百位 LCD_disp_char(14,1,Alarm/10%10+'0');//显示报警速度的 十位 LCD_disp_char(15,1,Alarm%10+'0');//显示报警速度的 个位 } /*------------------------------------- 主函数 ---------------------------------------*/ void main(void) { uint a; TIM0init();//定时器配置 EX0=1;//打开外部中断0 IT0=1;//下降沿触发 LCD_init();//LCD初始化 LCD_disp_str(0,1,"S:0000m/s BJ:000"); //显示 实时转速 LCD_disp_str(0,2," "); //显示 实时转速 while(1) { keyscan(); //按键扫描 Check();//测速程序 DisPlay();//LCD显示 if(a<500) { a++; } else { a=0; printf(":%dm/s\r",Speed); //串口通信 } } }这个代码运行结果不稳定 修改

时间: 2025-05-31 08:52:10 浏览: 31
### C程序运行不稳定的原因分析 C程序运行不稳定可能由多种因素引起,包括但不限于硬件资源不足、代码逻辑错误、外部干扰或编译器配置不当等问题。以下是针对 `reg52.h`、`intrins.h`、`math.h` 和 `stdio.h` 的修改建议及其原因: #### 1. **检查头文件的正确性和兼容性** 使用标准头文件时需注意其版本和目标平台的一致性。如果使用的头文件不匹配当前开发环境,则可能导致不可预测的行为。 - 对于单片机开发,`reg52.h` 是常用的寄存器定义头文件[^1]。确保该文件中的宏定义与实际芯片型号一致。 如果存在冲突或者未正确定义某些特殊功能寄存器(SFR),可能会引发访问异常。 - 针对数学运算需求引入了 `math.h` 头文件[^2]。需要注意的是,在嵌入式环境中调用复杂的浮点数计算会消耗大量存储空间并降低性能。因此应评估是否真的需要这些高级功能,并考虑简化算法替代复杂函数调用。 #### 2. **利用 intrins.h 提升效率减少不确定性** 文件 `intrins.h` 定义了一些底层指令级操作如 `_cror_`, `_crol_` 等用于处理位旋转等任务[^3]。适当运用此类内置函数可以提高执行速度同时避免因手动编写汇编片段带来的潜在风险。 示例展示如何安全地应用循环移位: ```c #include <intrins.h> unsigned char rotate_right(unsigned char value, unsigned int n){ return _cror_(value,n); } ``` #### 3. **合理使用 stdio.h 进行调试输出** 虽然可以通过 `printf()` 或者其他 I/O 流控制命令来辅助定位问题所在位置[^4] ,但在资源受限的小型设备上频繁打印消息会影响整体表现甚至造成死锁状况发生 。所以应当谨慎设置缓冲区大小以及刷新频率等相关参数以平衡诊断价值同实时响应之间的关系 。 综上所述,要改善 c 应用稳定性可以从以下几个方面入手 :优化所依赖库的选择范围;充分利用特定架构优势特性完成相应工作流程改造;最后还要记得测试验证改动后的效果直至达到预期目标为止 。 ```c #include <reg52.h> /* 单片机寄存器定义 */ #include <stdio.h> /* 输入输出流管理 */ #include <math.h> /* 数学运算支持 */ #include <intrins.h> /* 内置函数扩展 */ // 主函数声明遵循无返回值形式 void main(){ // 初始化部分省略... while(1){ // 循环主体业务逻辑保持简洁高效 // 添加必要的延时机制防止过快切换状态影响观测效果 __asm__("nop"); // 利用内部提供的工具方法代替原始编码提升可靠性 unsigned char data = 0xAA; data = _cror_(data , 1); // 右旋一位示例 } } ```
阅读全文

相关推荐

#include <reg51.h> #include <intrins.h> #include <stdio.h> #define uchar unsigned char #define uint unsigned int // 引脚定义 sbit RS = P2^0; // LCD1602 寄存器选择 sbit EN = P2^1; // LCD1602 使能 sbit D1 = P2^2; // 状态指示灯 sbit KEY = P3^2; // 复位按键 // 函数声明 void delay_ms(uint ms); // 毫秒级延时 void LCD_Init(); // LCD初始化 void LCD_WriteCommand(uchar cmd); // 写命令 void LCD_WriteData(uchar dat); // 写数据 void LCD_SetCursor(uchar row, uchar col); // 设置光标位置 void LCD_ShowString(uchar row, uchar col, uchar *str); // 显示字符串 void LCD_Clear(); // 清屏 uchar KeyScan(); // 键盘扫描 void Calculate(); // 计算函数 void DisplayResult(); // 显示计算结果 // 全局变量 uchar displayBuf[16]; // 显示缓冲区 uchar num1[5] = {0}; // 第一个操作数 uchar num2[5] = {0}; // 第二个操作数 uchar op = 0; // 运算符(0:无, '+', '-', '*', '/') uchar num1Index = 0; // 操作数1索引 uchar num2Index = 0; // 操作数2索引 uchar result[10] = {0}; // 计算结果 bit opFlag = 0; // 运算符标志 bit equalFlag = 0; // 等号标志 bit errorFlag = 0; // 错误标志 void main() { LCD_Init(); // 初始化LCD LCD_Clear(); LCD_ShowString(0, 0, "Simple Calculator"); LCD_SetCursor(1, 0); D1 = 1; // 点亮状态指示灯 while(1) { uchar key = KeyScan(); // 扫描键盘 if(key != 0xFF) { // 如果有按键按下 delay_ms(20); // 消抖 if(key != 0xFF) { // 确认按键有效 // 处理复位按键 if(KEY == 0) { delay_ms(20); if(KEY == 0) { while(KEY == 0); // 等待按键释放 // 复位所有变量和显示 LCD_Clear(); LCD_ShowString(0, 0, "Simple Calculator"); LCD_SetCursor(1, 0); memset(num1, 0, sizeof(num1)); memset(num2,

#include<reg52.h> #include<intrins.h> #include"i2c.h" #include"1602.h" #include"Pcf8591.h" unsigned char AD_CHANNEL; unsigned char TempData[12]; void disp(void) { LCD_Write_Char(2,0,'0'+TempData[0]); LCD_Write_Char(3,0,'.'); LCD_Write_Char(4,0,'0'+TempData[1]); LCD_Write_Char(5,0,'0'+TempData[2]); LCD_Write_Char(6,0,'V'); LCD_Write_Char(10,0,'0'+TempData[3]); LCD_Write_Char(11,0,'.'); LCD_Write_Char(12,0,'0'+TempData[4]); LCD_Write_Char(13,0,'0'+TempData[5]); LCD_Write_Char(14,0,'V'); LCD_Write_Char(2,0,'0'+TempData[6]); LCD_Write_Char(3,0,'.'); LCD_Write_Char(4,0,'0'+TempData[7]); LCD_Write_Char(5,0,'0'+TempData[8]); LCD_Write_Char(6,0,'V'); LCD_Write_Char(10,0,'0'+TempData[9]); LCD_Write_Char(11,0,'.'); LCD_Write_Char(12,0,'0'+TempData[10]); LCD_Write_Char(13,0,'0'+TempData[11]); LCD_Write_Char(14,0,'V'); } void mDelay(unsigned char j) { unsigned int i; for(;j>0;j--) { for(i=0;i<125;i++) {;} } } main() { unsigned char ADtemp; LCD_Init() ; LCD_Clear(); mDelay(20); while(1) { unsigned char AddWr; switch(AD_CHANNEL) { case 0: PCF8591_SendByte(AddWr,0); ADtemp=PCF8591_RcvByte(AddWr); ADtemp=PCF8591_RcvByte(AddWr); TempData[0]=ADtemp/51; TempData[1]=(ADtemp%51)*5*100/255/10; TempData[2]=(ADtemp%51)*5*100/255%10; break; case 1: PCF8591_SendByte(AddWr,1); ADtemp=PCF8591_RcvByte(AddWr); ADtemp=PCF8591_RcvByte(AddWr); TempData[3]=ADtemp/51; TempData[4]=(ADtemp%51)*5*100/255/10; TempData[5]=(ADtemp%51)*5*100/255%10; break; case 2: PCF8591_SendByte(AddWr,2); ADtemp=PCF8591_RcvByte(AddWr); ADtemp=PCF8591_RcvByte(AddWr); TempData[6]=ADtemp/51; TempData[7]=(ADtemp%51)*5*100/255/10; TempData[8]=(ADtemp%51)*5*100/255%10; break; case 3: PCF8591_SendByte(AddWr,3); ADtemp=PCF8591_RcvByte(AddWr); ADtemp=PCF8591_RcvByte(AddWr); TempData[9]=ADtemp/51; TempData[10]=(ADtemp%51)*5*100/255/10; TempData[11]=(ADtemp%51)*5*100/255%10; break; case 4: PCF8591_DaConversion(AddWr,0,ADtemp); break; } if(++AD_CHANNEL>4) AD_CHANNEL=0; disp(); } } #include<intrins.h> #include"i2c.h" #include"Pcf8591.h" bit Pcf8591_DaConversion(unsigned char addr, unsigned char channel, unsigned char Val) { Start_I2c(); I2C_SendByte(addr); I2C_SendByte(0x40|channel); I2C_SendByte(Val); Stop_I2c(); return(1); } bit Pcf8591_SendByte(unsigned char addr,unsigned char channel) { Start_I2c(); I2C_SendByte(addr); if(ack==0)return(0); I2C_SendByte(0x40|channel); if(ack==0)return(0); Stop_I2c(); return(1); } unsigned char Pcf8591_RcvByte(unsigned char addr) { unsigned char dat; Start_I2c(); I2C_SendByte(addr); if(ack==0)return(0); dat=I2C_RcvByte(); Ack_I2c(1); Stop_I2c(); return(dat); } #include<intrins.h> #include"i2c.h" #include"Pcf8591.h" bit Pcf8591_DaConversion(unsigned char addr, unsigned char channel, unsigned char Val) { Start_I2c(); I2C_SendByte(addr); I2C_SendByte(0x40|channel); I2C_SendByte(Val); Stop_I2c(); return(1); } bit Pcf8591_SendByte(unsigned char addr,unsigned char channel) { Start_I2c(); I2C_SendByte(addr); if(ack==0)return(0); I2C_SendByte(0x40|channel); if(ack==0)return(0); Stop_I2c(); return(1); } unsigned char Pcf8591_RcvByte(unsigned char addr) { unsigned char dat; Start_I2c(); I2C_SendByte(addr); if(ack==0)return(0); dat=I2C_RcvByte(); Ack_I2c(1); Stop_I2c(); return(dat); } #ifndef PCF8591_H #define PCF8591_H #include <reg52.h> // 函数声明 void PCF8591_Init(void); unsigned char PCF8591_SendByte(unsigned char addr, unsigned char channel); unsigned char PCF8591_RcvByte(unsigned char addr); unsigned char PCF8591_DaConversion(unsigned char addr, unsigned char channel, unsigned char Val); void disp(void); #endif // PCF8591_H #include <reg52.H> #include <intrins.H> #include <math.H> #include "delay.h" #include "1602.h" unsigned char table[]={0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00}; /*------------------------------------------------ 写入命令函数 ------------------------------------------------*/ void LCD_Write_Com(unsigned char com) { RS_CLR; RW_CLR; DataPort= com; EN_SET; delay(1); EN_CLR; delay(1); } /*------------------------------------------------ 写入数据函数 ------------------------------------------------*/ void LCD_Write_Data(unsigned char Data) { RS_SET; RW_CLR; DataPort= Data; EN_SET; delay(1); EN_CLR; delay(1); } /*------------------------------------------------ 清屏函数 ------------------------------------------------*/ void LCD_Clear(void) { LCD_Write_Com(0x01); delay(5); } /*------------------------------------------------ 写入字符函数 ------------------------------------------------*/ void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data) { if (y == 0) //设置坐标 { LCD_Write_Com(0x80 + x); } else { LCD_Write_Com(0xC0 + x); } LCD_Write_Data(Data); } /*------------------------------------------------ 初始化函数 ------------------------------------------------*/ void LCD_Init(void) { LCD_Write_Com(0x38); /*显示模式设置*/ delay(5); LCD_Write_Com(0x38); /*显示模式设置*/ delay(5); LCD_Write_Com(0x38); /*显示模式设置*/ delay(5); LCD_Write_Com(0x0C); /*显示开及光标设置*/ delay(5); LCD_Write_Com(0x06); /*显示光标移动设置*/ delay(5); LCD_Write_Com(0x01); /*显示清屏*/ } #include"i2c.h" #include <intrins.h> bit ack; /*应答标志位*/ /******************************************************************* 起动总线函数 函数原型: void Start_I2c(); 功能: 启动I2C总线,即发送I2C起始条件. ********************************************************************/ void Start_I2c() { sda=1; /*发送起始条件的数据信号*/ _nop_(); scl=1; _nop_(); /*起始条件建立时间大于4.7us,延时*/ _nop_(); _nop_(); _nop_(); _nop_(); sda=0; /*发送起始信号*/ _nop_(); /* 起始条件锁定时间大于4μs*/ _nop_(); _nop_(); _nop_(); _nop_(); scl=0; /*钳住I2C总线,准备发送或接收数据 */ _nop_(); _nop_(); } /******************************************************************* 结束总线函数 函数原型: void Stop_I2c(); 功能: 结束I2C总线,即发送I2C结束条件. ********************************************************************/ void Stop_I2c() { sda=0; /*发送结束条件的数据信号*/ _nop_(); /*发送结束条件的时钟信号*/ scl=1; /*结束条件建立时间大于4μs*/ _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); sda=1; /*发送I2C总线结束信号*/ _nop_(); _nop_(); _nop_(); _nop_(); } /******************************************************************* 字节数据发送函数 函数原型: void I2C_SendByte(UCHAR c); 功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对 此状态位进行操作.(不应答或非应答都使ack=0) 发送数据正常,ack=1; ack=0表示被控器无应答或损坏。 ********************************************************************/ void I2C_SendByte(unsigned char c) { unsigned char i; for(i=0;i<8;i++) /*要传送的数据长度为8位*/ { if((c<<i)&0x80)sda=1; /*判断发送位*/ else sda=0; _nop_(); scl=1; /*置时钟线为高,通知被控器开始接收数据位*/ _nop_(); _nop_(); /*保证时钟高电平周期大于4μs*/ _nop_(); _nop_(); _nop_(); scl=0; } _nop_(); _nop_(); sda=1; /*8位发送完后释放数据线,准备接收应答位*/ _nop_(); _nop_(); scl=1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); if(sda==1)ack=0; else ack=1; /*判断是否接收到应答信号*/ scl=0; _nop_(); _nop_(); } /******************************************************************* 字节数据接收函数 函数原型: UCHAR I2C_RcvByte(); 功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号), 发完后请用应答函数应答从机。 ********************************************************************/ unsigned char I2C_RcvByte() { unsigned char retc=0,i; sda=1; /*置数据线为输入方式*/ for(i=0;i<8;i++) { _nop_(); scl=0; /*置时钟线为低,准备接收数据位*/ _nop_(); _nop_(); /*时钟低电平周期大于4.7μs*/ _nop_(); _nop_(); _nop_(); scl=1; /*置时钟线为高使数据线上数据有效*/ _nop_(); _nop_(); retc=retc<<1; if(sda==1)retc=retc+1; /*读数据位,接收的数据位放入retc中 */ _nop_(); _nop_(); } scl=0; _nop_(); _nop_(); return(retc); } /******************************************************************** 应答子函数 函数原型: void Ack_I2c(bit a); 功能: 主控器进行应答信号(可以是应答或非应答信号,由位参数a决定) ********************************************************************/ void Ack_I2c(bit a) { if(a==0)sda=0; /*在此发出应答或非应答信号 */ else sda=1; /*0为发出应答,1为非应答信号 */ _nop_(); _nop_(); _nop_(); scl=1; _nop_(); _nop_(); /*时钟低电平周期大于4μs*/ _nop_(); _nop_(); _nop_(); scl=0; /*清时钟线,住I2C总线以便继续接收*/ _nop_(); _nop_(); } #include <reg52.H> #include <intrins.H> void delay(unsigned int xms) { unsigned int i,j; for(i=xms;i>0;i--) //i=xms即延时约xms毫秒 for(j=112;j>0;j--); } 对代码进行更改,要求1602显示上出现四个电压值,并且可以进行电压的变化

#include <reg51.h> #include <intrins.h> #define uchar unsigned char #define uint unsigned int // 硬件接口定义 #define SEG_PORT P0 // 段选 #define DIG_PORT P2 // 位选 sbit KEY_EXIT = P3^2; // 退出跑马灯的按键 // 共阳极数码管段码表 uchar code SEG_TAB[] = { 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, // 0-9 0xC7 // L }; // 全局变量 uchar Display_Buffer[6]; // 显示缓冲区 uchar Input_Buffer[10]; // 输入缓冲区 uchar Input_Index = 0; // 输入索引 bit Init_Mode = 1; // 初始化模式标志 bit Display_Mode = 0; // 0-输入模式 1-结果显示模式 /*----- 函数声明 -----*/ void delay_ms(uint ms); void clear_display(void); void display_digit(uchar pos, uchar value); bit check_key_press(void); void run_horse_init(void); void calculator_mode(void); void handle_input(uchar key); float calculate(void); void result_to_display(float result); /*----- 主函数 -----*/ void main(void) { // 初始化 run_horse_init(); // 跑马灯初始化(可按键退出) calculator_mode(); // 进入计算器主循环 } void delay_ms(uint ms) { uint i, j; for(i = 0; i < ms; i++) for(j = 0; j < 120; j++); } /** * @brief 清空所有数码管 */ void clear_display(void) { uchar i; for(i = 0; i < 6; i++) { display_digit(i, 0xFF); } } /** * @brief 在指定位置显示字符 */ void display_digit(uchar pos, uchar value) { DIG_PORT = ~(1 << pos); // 位选 SEG_PORT = value; // 段选 delay_ms(1); // 短暂延时 } /** * @brief 检测退出按键(P3.2) */ bit check_key_press(void) { if(KEY_EXIT == 0) { delay_ms(10); // 消抖 if(KEY_EXIT == 0) { while(!KEY_EXIT); // 等待释放 return 1; } } return 0; } /** * @brief 跑马灯初始化(可按键中断) */ void run_horse_init(void) { uchar i, pos = 0; while(Init_Mode) { // 更新显示(L从左到右移动) for(i = 0; i < 6; i++) { display_digit(i, (i == pos) ? SEG_TAB[10] : 0xFF); } // 检查按键 if(check_key_press()) { Init_Mode = 0; clear_displ

#include <reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 #include <intrins.h> #include <math.h> #define uchar unsigned char #define uint unsigned int sbit RS = P3^5; //定义端口 sbit RW = P3^6; sbit EN = P3^4; sbit DU = P2^6; sbit WE = P2^7; sbit Data = P2^1;//定义数据线 uchar rec_dat[15]; //用于显示的接收数据数组 #define RS_CLR RS=0 #define RS_SET RS=1 #define RW_CLR RW=0 #define RW_SET RW=1 #define EN_CLR EN=0 #define EN_SET EN=1 #define DataPort P0 void cmg88()//关数码管,点阵函数 { DU=1; P0=0X00; DU=0; } /*------------------------------------------------ uS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时 长度如下 T=tx2+5 uS ------------------------------------------------*/ void DelayUs2x(unsigned char t) { while(--t); } /*------------------------------------------------ mS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0~255 这里使用晶振12M,精确延时请使用汇编 ------------------------------------------------*/ void DelayMs(unsigned char t) { while(t--) { //大致延时1mS DelayUs2x(245); DelayUs2x(245); } } /*------------------------------------------------ 判忙函数 ------------------------------------------------*/ bit LCD_Check_Busy(void) { DataPort= 0xFF; RS_CLR; RW_SET; EN_CLR; _nop_(); EN_SET; return (bit)(DataPort & 0x80); } /*------------------------------------------------ 写入命令函数 ------------------------------------------------*/ void LCD_Write_Com(unsigned char com) { while(LCD_Check_Busy()); //忙则等待 RS_CLR; RW_CLR; EN_SET; DataPort= com; _nop_(); EN_CLR; } /*------------------------------------------------ 写入数据函数 ------------------------------------------------*/ void LCD_Write_Data(unsigned char Data) { while(LCD_Check_Busy()); //忙则等待 RS_SET; RW_CLR; EN_SET; DataPort= Data; _nop_(); EN_CLR; } /*------------------------------------------------ 清屏函数 ----------------------------------------

#include <reg52.h> #include <intrins.h> #include <math.h> #include <stdio.h> #include <string.h> #define uint unsigned int #define uchar unsigned char /* 硬件接口定义 */ sbit ADC_CS = P2^3; // ADC0804控制引脚 sbit ADC_RD = P2^4; sbit ADC_WR = P2^5; sbit ADC_INTR = P2^6; #define ADC_DATA P1 sbit DS18B20_DQ = P3^7; // DS18B20数据线 sbit TRIAC_CTRL = P2^7; // 可控硅控制引脚 sbit LCD_RS = P3^3; // LCD1602接口 sbit LCD_RW = P3^4; sbit LCD_EN = P3^5; #define LCD_DB P0 sbit BUZZER = P2^0; // 蜂鸣器 sbit KEY_UP = P3^0; // 按键 sbit KEY_DOWN = P3^1; sbit KEY_ENT = P3^2; /* 系统参数 */ #define SET_STEP 10.0 #define MAX_TEMP 1200.0 #define HYSTERESIS 3.0 #define SAFE_MARGIN 50.0 #define V_REF 5.0 #define ADC_MAX 255.0 #define GAIN 100.0 // AD620增益 #define K_TC_SLOPE 0.041 // K型热电偶灵敏度(41μV/℃) #define SAMPLE_TIME 200 // 200ms控制周期 /* PID参数 */ float Kp=2.5, Ki=0.02, Kd=0.8; float integral=0, last_err=0; /* 全局变量 */ idata char lcd_buf[16]; float current_temp=0.0, set_temp=600.0, ambient_temp=25.0; bit alarm_flag=0, set_mode=0; /* 温度查表数据 */ code float K_TC_Table[] = { 0.0, 0.0, // 0mV → 0℃ 4.095, 100.0, // 4.095mV → 100℃ 12.207, 300.0, 24.902, 600.0, 48.838, 1200.0 // 48.838mV → 1200℃ }; /* 函数声明 */ void sys_init(void); void lcd_init(void); void lcd_display(float now_temp, float set_temp); void keyscan(void); void pid_control(void); void alarm_check(void); void delay_ms(uint ms); void delay_us(uint us); uchar read_adc(void); float read_ds18b20(void); float adc_to_temp(uchar adc_val); float lookup_temperature(float voltage); void lcd_show_error(char *msg); bit ds18b20_reset(void); void ds18b20_write_byte(uchar dat); uchar ds18b20_read_byte(void); void write_cmd(uchar cmd); void write_data(uchar dat); void lcd_busy(void); /******************** 主函数 ********************/ void main() { sys_init(); lcd_init(); while(1) { ambient_temp = read_ds18b20(); // 读取冷端温度 current_temp = adc_to_temp(read_adc()); // 读取热电偶温度 keyscan(); // 按键处理 pid_control(); // PID温度控制 alarm_check(); // 安全检测 lcd_display(current_temp, set_temp); delay_ms(SAMPLE_TIME); // 系统周期 } } /******************** 系统初始化 ********************/ void sys_init() { // 外设初始化 ADC_CS = 1; ADC_RD = 1; ADC_WR = 1; TRIAC_CTRL = 0; BUZZER = 0; // 定时器0用于系统时钟 TMOD |= 0x01; // 模式1 TH0 = 0xFC; // 1ms定时 TL0 = 0x66; ET0 = 1; TR0 = 1; EA = 1; } /******************** 定时器0中断服务 ********************/ void timer0_isr() interrupt 1 { TH0 = 0xFC; // 重装初值 TL0 = 0x66; } /******************** PID控制算法 ********************/ void pid_control() { float err, output; err = set_temp - current_temp; // 积分抗饱和处理 if(fabs(err) < 100) { integral += err * SAMPLE_TIME / 1000.0; } // PID计算 output = Kp * err + Ki * integral + Kd * (err - last_err) * 1000.0 / SAMPLE_TIME; // 输出限幅和死区处理 if(output > 95.0) output = 95.0; else if(output < 5.0) output = 0.0; // PWM相位控制(周期20ms) if(output > 5.0) { TRIAC_CTRL = 1; delay_ms((uint)(output / 5.0)); TRIAC_CTRL = 0; delay_ms(20 - (uint)(output / 5.0)); } else { TRIAC_CTRL = 0; } last_err = err; } /******************** 温度计算与处理 ********************/ float adc_to_temp(uchar adc_val) { static uchar samples[16]; static uchar idx=0; uint sum=0; uchar i; float voltage, temp; // 滑动窗口滤波 samples[idx++%16] = adc_val; for(i=0; i<16; i++) sum += samples[i]; voltage = (sum >> 4) * V_REF / ADC_MAX / GAIN; // 冷端补偿 voltage += ambient_temp * K_TC_SLOPE / 1000.0; // 查表法温度转换 temp = lookup_temperature(voltage); // 传感器故障检测 if(adc_val < 5 || adc_val > 250) { lcd_show_error("SENSOR ERROR"); return -999.9; } return temp; } float lookup_temperature(float voltage) { uint i; voltage *= 1000; // 转换为mV for(i=2; i<sizeof(K_TC_Table)/sizeof(float); i+=2) { if(voltage <= K_TC_Table[i]) { float x1 = K_TC_Table[i-2]; float y1 = K_TC_Table[i-1]; float x2 = K_TC_Table[i]; float y2 = K_TC_Table[i+1]; return y1 + (voltage - x1) * (y2 - y1) / (x2 - x1); } } return MAX_TEMP; // 超量程 } /******************** DS18B20完整驱动程序 ********************/ float read_ds18b20(void) { uchar temp_l, temp_h; int temp; float t; if(!ds18b20_reset()) { // 复位失败处理 lcd_show_error("DS18B20 ERROR"); return -999.9; } ds18b20_write_byte(0xCC); // 跳过ROM命令 ds18b20_write_byte(0x44); // 启动温度转换 delay_ms(750); // 等待转换完成(12位精度) if(!ds18b20_reset()) { // 再次复位 return -999.9; } ds18b20_write_byte(0xCC); // 跳过ROM ds18b20_write_byte(0xBE); // 读取暂存器 temp_l = ds18b20_read_byte(); // 读取温度低字节 temp_h = ds18b20_read_byte(); // 读取温度高字节 temp = (temp_h << 8) | temp_l; t = temp * 0.0625; // 转换为实际温度 return t; } bit ds18b20_reset() { DS18B20_DQ = 0; delay_us(480); DS18B20_DQ = 1; delay_us(60); return (DS18B20_DQ == 0); } void ds18b20_write_byte(uchar dat) { uchar i; for(i=0; i<8; i++) { DS18B20_DQ = 0; delay_us(2); DS18B20_DQ = dat & 0x01; delay_us(60); DS18B20_DQ = 1; dat >>= 1; } } uchar ds18b20_read_byte() { uchar i, dat=0; for(i=0; i<8; i++) { DS18B20_DQ = 0; delay_us(2); DS18B20_DQ = 1; delay_us(8); dat >>= 1; // 修正位移方向 if(DS18B20_DQ) dat |= 0x80; delay_us(50); } return dat; } /******************** ADC0804驱动程序 ********************/ uchar read_adc() { uchar val; ADC_CS = 0; ADC_WR = 0; _nop_(); _nop_(); ADC_WR = 1; while(ADC_INTR == 1); // 等待转换完成 ADC_RD = 0; val = ADC_DATA; ADC_RD = 1; ADC_CS = 1; return val; } /******************** LCD1602驱动程序 ********************/ void lcd_init() { delay_ms(15); write_cmd(0x38); write_cmd(0x0C); write_cmd(0x06); write_cmd(0x01); } void lcd_display(float now_temp, float set_temp) { uchar i; if(now_temp < 0) { sprintf(lcd_buf, "NOW:----.-%cC ", 0xDF); } else { sprintf(lcd_buf, "NOW:%5.1f%cC", now_temp, 0xDF); } write_cmd(0x80); for(i=0; lcd_buf[i]; i++) write_data(lcd_buf[i]); sprintf(lcd_buf, "SET:%5.1f%cC", set_temp, 0xDF); write_cmd(0xC0); for(i=0; lcd_buf[i]; i++) write_data(lcd_buf[i]); } void lcd_show_error(char *msg) { uchar i; write_cmd(0x01); write_cmd(0x80); for(i=0; msg[i]; i++) write_data(msg[i]); } void write_cmd(uchar cmd) { lcd_busy(); LCD_RS = 0; LCD_RW = 0; LCD_DB = cmd; LCD_EN = 1; _nop_(); LCD_EN = 0; delay_ms(2); } void write_data(uchar dat) { lcd_busy(); LCD_RS = 1; LCD_RW = 0; LCD_DB = dat; LCD_EN = 1; _nop_(); LCD_EN = 0; delay_ms(1); } void lcd_busy() { LCD_DB = 0xFF; LCD_RS = 0; LCD_RW = 1; do { LCD_EN = 1; _nop_(); LCD_EN = 0; } while (LCD_DB & 0x80); } /******************** 按键扫描程序 ********************/ void keyscan() { static bit key_lock = 0; if(!KEY_ENT && !key_lock) { delay_ms(20); if(!KEY_ENT) { set_mode = ~set_mode; key_lock = 1; BUZZER = 1; delay_ms(50); BUZZER = 0; } } else if(KEY_ENT) { key_lock = 0; } if(set_mode) { if(!KEY_UP) { delay_ms(20); if(!KEY_UP) { set_temp += SET_STEP; if(set_temp > MAX_TEMP) set_temp = MAX_TEMP; while(!KEY_UP); } } if(!KEY_DOWN) { delay_ms(20); if(!KEY_DOWN) { set_temp -= SET_STEP; if(set_temp < 0) set_temp = 0; while(!KEY_DOWN); } } } } /******************** 报警与安全系统 ********************/ void alarm_check() { static uchar alarm_cnt = 0; if(current_temp < 0 || current_temp > MAX_TEMP) { BUZZER = 1; TRIAC_CTRL = 0; alarm_flag = 1; } else if(fabs(current_temp - set_temp) > SAFE_MARGIN) { if(++alarm_cnt > 10) { BUZZER = ~BUZZER; alarm_cnt = 0; } alarm_flag = 1; } else { BUZZER = 0; alarm_flag = 0; alarm_cnt = 0; } } /******************** 延时函数 ********************/ void delay_ms(uint ms) { uint i, j; for(i=0; i<ms; i++) for(j=0; j<114; j++); } void delay_us(uint us) { while(us--) { _nop_(); _nop_(); _nop_(); _nop_(); } }根据此代码找出LCD不显示的原因

#include <reg52.h> //Í·Îļþ #include <intrins.h> #include <stdio.h> #include <math.h> #define uint unsigned int #define uchar unsigned char #define ulong unsigned long uchar s1num,shape,num,a,b,c,d,e,f,h,boxing; ulong Freq,g; uint Config_Data[8]; uchar code table1[]="²¨ÐÎÑ¡Ôñ : SIN "; uchar code table2[]="²¨ÐÎÆµÂÊ : "; uchar code table3[]="0 0 0 0 0 0 0 HZ"; uchar code table4[]="DDS Ðźŷ¢ÉúÆ÷ "; sbit rs=P2^7; //12864Òº¾§¶Ë¿ÚµÄ¶¨Òå sbit rw=P2^6; sbit ep=P2^5; sbit lcd_psb=P2^4; sbit FSYNC=P1^4; //AD9833¶Ë¿ÚµÄ¶¨Òå sbit SCLK =P1^3; sbit SDATA=P1^2; sbit s1=P2^0; //¹â±ê¼ü sbit s2=P2^1; //Éϵ÷¼ü sbit s3=P2^2; //ϵ÷¼ü void Wave_Generate(ulong,uchar); //²¨ÐÎµÄÆµÂʺͲ¨ÐεÄÑ¡Ôñ void AD9833_Send_Word(uint); //AD9833µÄÊý¾Ý½ÓÊÕº¯Êý void delay(uint); //ÑÓʱº¯Êý void delay(uint xms) { uint i,j; for(i=xms;i>0;i--) for(j=110;j>0;j--); } void lcd_cmd(uchar cmd) //12864дÈëµÄÖ¸Áî { rs=0; rw=0; ep=0; P0=cmd; delay(5); ep=1; delay(5); ep=0; } void lcd_dat(uchar dat) //12864дÈëµÄÊý¾Ý { rs=1; rw=0; ep=0; P0=dat; delay(5); ep=1; delay(5); ep=0; } void lcd_init() //12864Òº¾§µÄ³õʼ»¯ { lcd_psb=1; delay(5); lcd_cmd(0x34); delay(5); lcd_cmd(0x30); delay(5); lcd_cmd(0x0c); delay(5); lcd_cmd(0x01); delay(5); } void display() { uint i; lcd_cmd(0x80); //µÚÒ»ÐÐÏÔʾ while(table1[i]!='\0') { lcd_dat(table1[i]); i++; } i=0; lcd_cmd(0x90); //µÚ¶þÐÐÏÔʾ while(table2[i]!='\0') { lcd_dat(table2[i]); i++; } i=0; lcd_cmd(0x88); //µÚÈýÐÐÏÔʾ while(table3[i]!='\0') { lcd_dat(table3[i]); i++; } i=0; lcd_cmd(0x98); //µÚËÄÐÐÏÔʾ while(table4[i]!='\0') { lcd_dat(table4[i]); i++; } } void input_freq() //¾ØÐμüÅÌɨÃ躯Êý { if(s1==0) //¹â±ê¼ü { delay(5); if(s1==0) { s1num++; while(!s1); lcd_cmd(0x0f); if(s1num==1) { lcd_cmd(0x80+7); } if(s1num==2) { lcd_cmd(0x88+6); } if(s1num==3) { lcd_cmd(0x88+5); } if(s1num==4) { lcd_cmd(0x88+4); } if(s1num==5) { lcd_cmd(0x88+3); } if(s1num==6) { lcd_cmd(0x88+2); } if(s1num==7) { lcd_cmd(0x88+1); } if(s1num==8) { lcd_cmd(0x88+0); } if(s1num==9) { s1num=0; lcd_cmd(0x0c); g=a+10*b+100*c+1000*d+10000*e+100000*f+1000000*h; Freq=g; boxing=shape; Wave_Generate(Freq,boxing); } } } if(s1num!=0) //Éϵ÷¼ü { if(s2==0) { delay(5); if(s2==0) { while(!s2); if(s1num==1) { shape++; if(shape==3) shape=0; lcd_cmd(0x80+6); switch(shape) { case 0: lcd_dat('S'); //°´0ΪÕýÏÒ²¨ delay(5); lcd_dat('I'); delay(5); lcd_dat('N'); delay(5); break; case 1: lcd_dat('T'); //°´1ΪÈý½Ç²¨ delay(5); lcd_dat('R'); delay(5); lcd_dat('I'); delay(5); break; case 2: lcd_dat('D'); //°´2Ϊ·½²¨ delay(5); lcd_dat('A'); delay(5); lcd_dat('C'); delay(5); break; } } if(s1num==2) { a++; if(a==10) a=0; lcd_cmd(0x88+6); lcd_dat(0x30+a); } if(s1num==3) { b++; if(b==10) b=0; lcd_cmd(0x88+5); lcd_dat(0x30+b); } if(s1num==4) { c++; if(c==10) c=0; lcd_cmd(0x88+4); lcd_dat(0x30+c); } if(s1num==5) { d++; if(d==10) d=0; lcd_cmd(0x88+3); lcd_dat(0x30+d); } if(s1num==6) { e++; if(e==10) e=0; lcd_cmd(0x88+2); lcd_dat(0x30+e); } if(s1num==7) { f++; if(f==10) f=0; lcd_cmd(0x88+1); lcd_dat(0x30+f); } if(s1num==8) { h++; if(h==10) h=0; lcd_cmd(0x88+0); lcd_dat(0x30+h); } } } } if(s1num!=0) { if(s3==0) { delay(5); if(s3==0) { while(!s3); if(s1num==1) { shape--; if(shape==-1) shape=2; lcd_cmd(0x80+6); switch(shape) { case 0: lcd_dat('S'); //°´0ΪÕýÏÒ²¨ delay(5); lcd_dat('I'); delay(5); lcd_dat('N'); delay(5); break; case 1: lcd_dat('T'); //°´1ΪÈý½Ç²¨ delay(5); lcd_dat('R'); delay(5); lcd_dat('I'); delay(5); break; case 2: lcd_dat('D'); //°´2Ϊ·½²¨ delay(5); lcd_dat('A'); delay(5); lcd_dat('C'); delay(5); break; } } if(s1num==2) { a--; if(a==-1) a=9; lcd_cmd(0x88+6); lcd_dat(0x30+a); } if(s1num==3) { b--; if(b==-1) b=9; lcd_cmd(0x88+5); lcd_dat(0x30+b); } if(s1num==4) { c--; if(c==-1) c=9; lcd_cmd(0x88+4); lcd_dat(0x30+c); } if(s1num==5) { d--; if(d==-1) d=9; lcd_cmd(0x88+3); lcd_dat(0x30+d); } if(s1num==6) { e--; if(e==-1) e=9; lcd_cmd(0x88+2); lcd_dat(0x30+e); } if(s1num==7) { f--; if(f==-1) f=9; lcd_cmd(0x88+1); lcd_dat(0x30+f); } if(s1num==8) { h--; if(h==-1) h=9; lcd_cmd(0x88+0); lcd_dat(0x30+h); } } } } } void main() { P0=0xff; P1=0xff; P2=0xff; P3=0xff; //delay(10000); lcd_init(); display(); FSYNC=1; SCLK=0; delay(5); Wave_Generate(1000,0); while(1) { input_freq(); } } void AD9833_Send_Word(uint Data_In) { uchar i; SCLK=1; FSYNC=0; for(i=0;i<16;i++) { SCLK=1; SDATA=(bit)((Data_In & 0x8000)>>15); SCLK=0; Data_In=Data_In<<1; } FSYNC=1; SCLK=0; } void Wave_Generate(ulong Freq,uchar shape) { ulong temp; uchar k; if(Freq>12000000) Freq=12000000; switch(shape) { case 0: Config_Data[0]=0x2108; //°´0ΪÕýÏÒ²¨ Config_Data[7]=0x2008; break; case 1: Config_Data[0]=0x210A; //°´1ΪÈý½Ç²¨ Config_Data[7]=0x200A; break; case 2: Config_Data[0]=0x2128; //°´2Ϊ·½²¨ Config_Data[7]=0x2028; break; default: Config_Data[0]=0x2108; Config_Data[7]=0x2008; } temp=Freq*10.73; //temp=Freq*(0x10000000/20000000); Config_Data[1]=temp&0x00003fff; Config_Data[3]=Config_Data[1]; Config_Data[2]=(temp&0x0fffc000)>>14; Config_Data[4]=Config_Data[2]; Config_Data[1]=Config_Data[1]|0x4000; Config_Data[2]=Config_Data[2]|0x4000; Config_Data[3]=Config_Data[3]|0x8000; Config_Data[4]=Config_Data[4]|0x8000; Config_Data[5]=0xC000; Config_Data[6]=0xE000; for(k=0;k<8;k++) { AD9833_Send_Word(Config_Data[k]); } } 上述程序中的液晶显示换成LCD1602,完整的程序写出来

#include <reg52.h> #include <intrins.h> // 硬件引脚定义 #define LED P1_0 // PWM输出引脚 #define KEY_BRIGHT P3_2 // 亮度切换按键 #define KEY_SWITCH P3_3 // 开关切换按键 #define BUZZER P2_0 // 蜂鸣器控制 #define DS18B20 P3_7 // 温度传感器 // LCD1602控制线 sbit LCD_RS = P2^1; sbit LCD_RW = P2^2; sbit LCD_EN = P2^3; #define LCD_DATA P0 // LCD数据总线 // 全局变量 bit led_state = 1; // LED开关状态(1:开, 0:关) bit key_flag = 0; // 按键触发标志 unsigned char brightness = 2; // 亮度等级(0-4) unsigned int pwm_count = 0; // PWM计数器 float temperature = 0.0; // 温度值 // 定时器0初始化 - PWM生成 void Timer0_Init() { TMOD |= 0x01; // 定时器0模式1 TH0 = 0xFC; // 1ms定时初值(11.0592MHz) TL0 = 0x18; ET0 = 1; // 使能定时器0中断 TR0 = 1; // 启动定时器 EA = 1; // 开总中断 } // 定时器0中断服务 - PWM输出 void Timer0_ISR() interrupt 1 { TH0 = 0xFC; // 重装初值 TL0 = 0x18; pwm_count++; if(pwm_count > 4) pwm_count = 0; // 5级周期 // 根据亮度和状态输出PWM if(led_state && (pwm_count < brightness)) LED = 1; // 高电平 else LED = 0; // 低电平 } // 按键扫描函数 void Key_Scan() { static unsigned int press_time = 0; // 亮度切换按键(短按) if(KEY_BRIGHT == 0) { delay_ms(10); // 消抖 if(KEY_BRIGHT == 0) { brightness = (brightness + 1) % 5; // 循环切换0-4 Beep(100); // 短提示音 key_flag = 1; while(!KEY_BRIGHT); // 等待释放 } } // 开关切换按键(长按检测) if(KEY_SWITCH == 0) { delay_ms(10); // 消抖 if(KEY_SWITCH == 0) { press_time = 0; while(!KEY_SWITCH) { delay_ms(10); press_time++; if(press_time > 200) { // 2秒长按 led_state = !led_state; Beep(500); // 长提示音 key_flag = 1; break; } } } } } // 蜂鸣器提示音 void Beep(unsigned int duration) { BUZZER = 0; // 开启蜂鸣器 delay_ms(duration); // 延时 BUZZER = 1; // 关闭蜂鸣器 } // LCD写命令 void LCD_WriteCmd(unsigned char cmd) { LCD_RS = 0; // 命令模式 LCD_RW = 0; // 写操作 LCD_DATA = cmd; LCD_EN = 1; delay_ms(2); LCD_EN = 0; } // LCD写数据 void LCD_WriteData(unsigned char dat) { LCD_RS = 1; // 数据模式 LCD_RW = 0; LCD_DATA = dat; LCD_EN = 1; delay_ms(2); LCD_EN = 0; } // LCD初始化 void LCD_Init() { LCD_WriteCmd(0x38); // 8位数据,2行显示 LCD_WriteCmd(0x0C); // 开显示,无光标 LCD_WriteCmd(0x06); // 地址递增,不移屏 LCD_WriteCmd(0x01); // 清屏 } // 更新LCD显示 void Update_Display() { char str[16]; // 第一行:亮度和开关状态 LCD_WriteCmd(0x80); // 第一行起始位置 sprintf(str, "Bright:%d%% %s", brightness*25, led_state?"ON ":"OFF"); for(int i=0; str[i]!='\0'; i++) { LCD_WriteData(str[i]); } // 第二行:温度显示 LCD_WriteCmd(0xC0); // 第二行起始位置 sprintf(str, "Temp:%.1fC", temperature); for(int i=0; str[i]!='\0'; i++) { LCD_WriteData(str[i]); } } // DS18B20复位 void DS18B20_Reset() { DS18B20 = 0; delay_us(480); // 480us低电平 DS18B20 = 1; delay_us(60); // 60us等待 while(DS18B20); // 等待应答 delay_us(420); // 480-60=420us } // 写1字节到DS18B20 void DS18B20_WriteByte(unsigned char dat) { for(int i=0; i<8; i++) { DS18B20 = 0; _nop_();_nop_(); // 延时2us DS18B20 = dat & 0x01; delay_us(60); // 60us维持 DS18B20 = 1; dat >>= 1; } } // 从DS18B20读1字节 unsigned char DS18B20_ReadByte() { unsigned char dat = 0; for(int i=0; i<8; i++) { dat >>= 1; DS18B20 = 0; _nop_();_nop_(); // 2us DS18B20 = 1; if(DS18B20) dat |= 0x80; delay_us(60); } return dat; } // 读取温度值 float Read_Temperature() { unsigned char LSB, MSB; DS18B20_Reset(); DS18B20_WriteByte(0xCC); // 跳过ROM DS18B20_WriteByte(0x44); // 启动转换 delay_ms(750); // 转换等待 DS18B20_Reset(); DS18B20_WriteByte(0xCC); DS18B20_WriteByte(0xBE); // 读温度 LSB = DS18B20_ReadByte(); MSB = DS18B20_ReadByte(); return ((MSB << 8) | LSB) * 0.0625; // 转换温度值 } void main() { // 初始化 Timer0_Init(); // PWM定时器 LCD_Init(); // LCD初始化 BUZZER = 1; // 关闭蜂鸣器 // 主循环 while(1) { Key_Scan(); // 按键扫描 if(key_flag) { // 按键触发更新 Update_Display(); key_flag = 0; } // 每2秒读取一次温度 static unsigned int temp_timer = 0; if(++temp_timer >= 2000) { temperature = Read_Temperature(); Update_Display(); temp_timer = 0; } delay_ms(1); // 主循环延时 } } // 简单延时函数 void delay_ms(unsigned int ms) { unsigned int i, j; for(i=0; i<ms; i++) for(j=0; j<114; j++); } // ADC读取函数(需硬件支持ADC0832) unsigned char Read_ADC() { // ADC转换代码... } // 主循环中添加 unsigned char adc_val = Read_ADC(); brightness = adc_val / 51; // 0-255映射到0-4 // 在定时器中断中添加呼吸效果 static bit breathe_dir = 0; if(breathe_dir) { if(++brightness >= 4) breathe_dir = 0; } else { if(--brightness <= 0) breathe_dir = 1; } // 温度超限报警 if(temperature > 40.0) { BUZZER = 0; // 开启蜂鸣器 // LCD显示报警信息 } else { BUZZER = 1; } 修改完善

/* * ADXL345步数计数器 - 带开始/停止控制版本 * 单页显示:步数+加速度+温度+时间 * 通过按钮控制计步开始/停止 */ #include <REG51.H> #include <math.h> #include <stdio.h> #include <INTRINS.H> #include "ds18b20.h" #include "ds1302.h" // 类型定义简化 #define uchar unsigned char #define uint unsigned int // 硬件端口定义 #define DataPort P0 // LCD1602数据端口 sbit SCL = P1^2; // IIC时钟引脚 sbit SDA = P1^3; // IIC数据引脚 sbit LCM_RS = P2^6; // LCD1602命令端口 sbit LCM_RW = P2^5; // LCD1602命令端口 sbit LCM_EN = P2^7; // LCD1602命令端口 sbit RESET_BTN = P3^2; // 复位按钮 sbit STARTSTOP_BTN = P3^0; // 开始/停止按钮 // ADXL345常量定义 #define ADXL345_ADDR 0xA6 // I2C地址(ALT ADDRESS接地) #define SAMPLE_RATE 50 // 采样间隔(ms) // 全局变量 uint step_count = 0; // 步数计数器 float step_threshold = 0.5; // 步数检测阈值 bit step_flag = 0; // 步数检测标志 bit counting_enabled = 0; // 计步使能标志 uchar display_buf[5]; // 显示缓冲区 int temp_value; // 温度值 uchar time_buf[9]; // 时间显示缓冲区 // 函数声明 void lcd_init(void); void lcd_write_cmd(uchar cmd); void lcd_write_data(uchar dat); void lcd_display_char(uchar x, uchar y, uchar ch); void adxl345_init(void); void adxl345_write(uchar reg, uchar val); uchar adxl345_read(uchar reg); float calculate_accel(void); void detect_step(float accel); void update_display(void); void convert_number(uint num, uchar* buf); void system_delay_ms(uint ms); void check_buttons(void); void toggle_counting(void); /*******************************/ /* LCD1602驱动函数 */ void lcd_busy_wait(void) { DataPort = 0xFF; LCM_RS = 0; LCM_RW = 1; _nop_(); LCM_EN = 1; _nop_(); _nop_(); while(DataPort & 0x80); LCM_EN = 0; } void lcd_write_cmd(uchar cmd) { lcd_busy_wait(); LCM_RS = 0; LCM_RW = 0; _nop_(); DataPort = cmd; _nop_(); LCM_EN = 1; _nop_(); _nop_(); LCM_EN = 0; } void lcd_write_data(uchar dat) { lcd_busy_wait(); LCM_RS = 1; LCM_RW = 0; _nop_(); DataPort = dat; _nop_(); LCM_EN = 1; _nop_(); _nop_(); LCM_EN = 0; } void lcd_display_char(uchar x, uchar y, uchar ch) { if(y) x |= 0x40; x |= 0x80; lcd_write_cmd(x); lcd_write_data(ch); } void lcd_init(void) { lcd_write_cmd(0x38); // 8位数据,双行显示,5×7点阵 lcd_write_cmd(0x0C); // 开显示,不显示光标 lcd_write_cmd(0x06); // 光标右移 lcd_write_cmd(0x01); // 清屏 system_delay_ms(2); // 确保初始化完成 } /*******************************/ /* 数字转换函数 */ void convert_number(uint num, uchar* buf) { buf[0] = num / 10000 + '0'; num %= 10000; buf[1] = num / 1000 + '0'; num %= 1000; buf[2] = num / 100 + '0'; num %= 100; buf[3] = num / 10 + '0'; num %= 10; buf[4] = num + '0'; } /*******************************/ /* 延时函数 */ void system_delay_ms(uint ms) { uint i, j; for(i = 0; i < ms; i++) for(j = 0; j < 121; j++); } /*******************************/ /* 按钮检测函数 */ void check_buttons(void) { // 检测复位按钮 if(!RESET_BTN) { system_delay_ms(10); // 消抖 if(!RESET_BTN) { step_count = 0; // 手动清零步数 while(!RESET_BTN); // 等待释放 } } // 检测开始/停止按钮 if(!STARTSTOP_BTN) { system_delay_ms(10); // 消抖 if(!STARTSTOP_BTN) { toggle_counting(); while(!STARTSTOP_BTN); // 等待释放 } } } /*******************************/ /* 开始/停止计数函数 */ void toggle_counting(void) { counting_enabled = !counting_enabled; } /*******************************/ /* I2C通信函数 */ void i2c_delay(void) { _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } void i2c_start(void) { SDA = 1; SCL = 1; i2c_delay(); SDA = 0; i2c_delay(); SCL = 0; } void i2c_stop(void) { SDA = 0; SCL = 1; i2c_delay(); SDA = 1; i2c_delay(); } bit i2c_send_byte(uchar dat) { uchar i; for(i = 0; i < 8; i++) { SDA = (dat & 0x80) ? 1 : 0; SCL = 1; i2c_delay(); SCL = 0; i2c_delay(); dat <<= 1; } SDA = 1; SCL = 1; i2c_delay(); dat = SDA; // 读取ACK SCL = 0; return dat; } uchar i2c_recv_byte(void) { uchar i, dat = 0; SDA = 1; for(i = 0; i < 8; i++) { dat <<= 1; SCL = 1; i2c_delay(); if(SDA) dat |= 0x01; SCL = 0; i2c_delay(); } return dat; } /*******************************/ /* ADXL345驱动函数 */ void adxl345_write(uchar reg, uchar val) { i2c_start(); i2c_send_byte(ADXL345_ADDR); i2c_send_byte(reg); i2c_send_byte(val); i2c_stop(); } uchar adxl345_read(uchar reg) { uchar val; i2c_start(); i2c_send_byte(ADXL345_ADDR); i2c_send_byte(reg); i2c_start(); i2c_send_byte(ADXL345_ADDR | 0x01); val = i2c_recv_byte(); i2c_stop(); return val; } void adxl345_init(void) { adxl345_write(0x31, 0x0B); // ±16g, 13位模式 adxl345_write(0x2C, 0x08); // 12.5Hz输出速率 adxl345_write(0x2D, 0x08); // 测量模式 adxl345_write(0x2E, 0x80); // 使能DATA_READY中断 adxl345_write(0x1E, 0x00); // X轴偏移 adxl345_write(0x1F, 0x00); // Y轴偏移 adxl345_write(0x20, 0x05); // Z轴偏移 } /*******************************/ /* 步数检测算法 */ float calculate_accel(void) { int x, y, z; x = (int)(adxl345_read(0x33) << 8) | adxl345_read(0x32); y = (int)(adxl345_read(0x35) << 8) | adxl345_read(0x34); z = (int)(adxl345_read(0x37) << 8) | adxl345_read(0x36); // 转换为g单位(3.9mg/LSB)并去除重力影响 return sqrt(x*x + y*y + z*z) * 0.0039; } // 步数检测算法 void detect_step(float accel) { static float accel_buffer[3] = {0}; static uchar buffer_index = 0; static bit was_above_threshold = 0; // 如果计步功能未启用,直接返回 if(!counting_enabled) return; // 更新加速度缓冲区 accel_buffer[buffer_index] = accel; buffer_index = (buffer_index + 1) % 3; // 检测峰值模式 if(!was_above_threshold && accel_buffer[(buffer_index+2)%3] < step_threshold && accel_buffer[(buffer_index+1)%3] >= step_threshold && accel_buffer[buffer_index] < step_threshold) { step_count++; was_above_threshold = 1; } else if(accel < step_threshold*0.8) { was_above_threshold = 0; } } /*******************************/ /* 显示更新函数 - 单页显示所有信息 */ void update_display(void) { static uchar counter = 0; float accel; uchar i, start; int accel_display; // 每10次循环读取一次温度(约500ms) if(++counter >= 10) { counter = 0; temp_value = ds18b20_read_temperture() * 100; // 读取并转换时间 ds1302_read_time(); time_buf[0] = gDS1302_TIME[2] / 16 + '0'; time_buf[1] = gDS1302_TIME[2] % 16 + '0'; time_buf[2] = ':'; time_buf[3] = gDS1302_TIME[1] / 16 + '0'; time_buf[4] = gDS1302_TIME[1] % 16 + '0'; time_buf[5] = ':'; time_buf[6] = gDS1302_TIME[0] / 16 + '0'; time_buf[7] = gDS1302_TIME[0] % 16 + '0'; } // 清屏 lcd_write_cmd(0x01); // 显示计步状态 lcd_display_char(15, 0, counting_enabled ? 'R' : 'S'); // R:运行, S:停止 // 第一行:步数和加速度 lcd_display_char(0, 0, 'S'); lcd_display_char(1, 0, 'T'); lcd_display_char(2, 0, 'E'); lcd_display_char(3, 0, 'P'); lcd_display_char(4, 0, ':'); // 显示步数 convert_number(step_count, display_buf); start = 0; while(start < 4 && display_buf[start] == '0') start++; for(i = start; i < 5; i++) { lcd_display_char(5+i-start, 0, display_buf[i]); } // 第二行:温度和时间 // 显示温度 lcd_display_char(0, 1, 'T'); lcd_display_char(1, 1, 'E'); lcd_display_char(2, 1, 'M'); lcd_display_char(3, 1, 'P'); lcd_display_char(4, 1, ':'); // 转换温度显示 (假设温度为正) display_buf[0] = temp_value / 1000 + '0'; display_buf[1] = (temp_value % 1000) / 100 + '0'; display_buf[2] = '.'; display_buf[3] = (temp_value % 100) / 10 + '0'; display_buf[4] = 'C'; for(i = 0; i < 5; i++) { lcd_display_char(5+i, 1, display_buf[i]); } // 显示时间 lcd_display_char(11, 1, 'T'); lcd_display_char(12, 1, ':'); for(i = 0; i < 8; i++) { lcd_display_char(13+i, 1, time_buf[i]); } // 在第二行显示加速度值(空间有限,只显示整数部分) accel = calculate_accel(); accel_display = (int)accel; convert_number(accel_display, display_buf); lcd_display_char(10, 0, 'A'); lcd_display_char(11, 0, ':'); lcd_display_char(12, 0, display_buf[4]); // 只显示个位数 lcd_display_char(13, 0, 'g'); } /*******************************/ /* 主函数 */ void main(void) { // 初始化硬件 ds18b20_init(); ds1302_init(); lcd_init(); adxl345_init(); // 验证设备ID if(adxl345_read(0x00) != 0xE5) { lcd_display_char(0, 0, 'E'); lcd_display_char(1, 0, 'R'); lcd_display_char(2, 0, 'R'); lcd_display_char(3, 0, 'O'); lcd_display_char(4, 0, 'R'); while(1); } // 显示欢迎信息 lcd_display_char(0, 0, 'S'); lcd_display_char(1, 0, 'T'); lcd_display_char(2, 0, 'E'); lcd_display_char(3, 0, 'P'); lcd_display_char(4, 0, ' '); lcd_display_char(5, 0, 'C'); lcd_display_char(6, 0, 'O'); lcd_display_char(7, 0, 'U'); lcd_display_char(8, 0, 'N'); lcd_display_char(9, 0, 'T'); lcd_display_char(10, 0, 'E'); lcd_display_char(11, 0, 'R'); system_delay_ms(1000); // 主循环 while(1) { // 读取加速度数据并检测步数 detect_step(calculate_accel()); // 更新显示 update_display(); // 检测按钮 check_buttons(); // 采样间隔延时 system_delay_ms(SAMPLE_RATE); } }以原代码为基础增加一个LED报警闪烁器报警功能 每走十步使管脚P2^1控制的灯闪烁两秒 输出完整代码

#include <reg52.h> #include <intrins.h> #include <absacc.h> #include <math.h> #include "0832.h" #define uchar unsigned char #define uint unsigned int #include "eeprom52.h" sbit DATA = P3^7; //温湿度 sbit E=P2^7; //1602使能引脚 sbit RS=P2^5; //1602数据/命令选择引脚 sbit RW=P2^6; sbit K1=P1^3;//设置键 sbit K2=P1^4;//加 sbit K3=P1^5;//减 sbit LED1=P3^1; //烟雾报警 sbit LED2=P3^2; //温度上限 sbit LED3=P3^3; //温度下限 sbit LED4=P3^4; //湿度上限 sbit LED5=P3^5; //湿度下限 sbit LED6=P3^6; //红外报警 sbit alarm=P3^0; //蜂鸣器 uchar U8FLAG,U8temp,U8comdata,U8RH_data_H_temp,U8RH_data_L_temp,U8T_data_H_temp,U8T_data_L_temp,U8checkdata_temp; uchar U8RH_data_H,U8RH_data_L,U8T_data_H,U8T_data_L,U8checkdata; uchar Mode,humidity,temperature,smog; bit flag_BJ=0; uchar PM_Counter=0; uint sum=0; uint DA=0; bit bdata FlagStartRH; uchar flag ;//记录当前设置状态 uint count; //定时器0初始化 void Timer0_Init() { ET0 = 1; //允许定时器0中断 TMOD = 0x11; //定时器工作方式选择 TL0 = 0xb0; TH0 = 0x3c; //定时器赋予初值 TR0 = 1; //启动定时器 TH1=0xdc; TL1=0x00; ET1=1; EA=1; } //定时器0中断 void Timer0_ISR (void) interrupt 1 { uchar RHCounter; TL0 = 0xb0; TH0 = 0x3c; //定时器赋予初值 RHCounter++; PM_Counter++; if(RHCounter%2==0&&flag_BJ==1) { alarm=!alarm; } if(RHCounter >= 20) { FlagStartRH = 1; RHCounter = 0; } if(PM_Counter%2==0) { DA=adc0832(0); PM_NUM=DA*100/255; } } //延时函数 void Delay1(uint j) { uchar i; for(;j>0;j--) { for(i=0;i<27;i++); } } //演示函数 void Delay_10us(void) { uchar i; i--; i--; i--; i--; i--; i--; } //ADC0832数据读取函数 void COM(void) { uchar i; for(i=0;i<8;i++) { U8FLAG=2; while((!DATA)&&U8FLAG++); Delay_10us(); Delay_10us(); Delay_10us(); U8temp=0; if(DATA)U8temp=1; U8FLAG=2; while((DATA)&&U8FLAG++); //超时则跳出for循环 if(U8FLAG==1)break; //判断数据位是0还是1 // 如果高电平高过预定0高电平值则数据位为 1 U8comdata<<=1; U8comdata|=U8temp; //0 }//rof } //-------------------------------- //-----温湿度读取子程序 ------------ //-------------------------------- //----以下变量均为全局变量-------- //----温度高8位== U8T_data_H------ //----温度低8位== U8T_data_L------ //----湿度高8位== U8RH_data_H----- //----湿度低8位== U8RH_data_L----- //----校验 8位 == U8checkdata----- //----调用相关子程序如下---------- //---- Delay();, Delay_10us();,COM(); //-------------------------------- uchar RH(void) { //主机拉低18ms DATA=0; Delay1(180); //原来为5 DATA=1; //总线由上拉电阻拉高 主机延时20us Delay_10us(); Delay_10us(); Delay_10us(); Delay_10us(); //主机设为输入 判断从机响应信号 DATA=1; //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行 if(!DATA) //T ! { U8FLAG=2; //判断从机是否发出 80us 的低电平响应信号是否结束 while((!DATA)&&U8FLAG++); U8FLAG=2; //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态 while((DATA)&&U8FLAG++); //数据接收状态 COM(); U8RH_data_H_temp=U8comdata; COM(); U8RH_data_L_temp=U8comdata; COM(); U8T_data_H_temp=U8comdata; COM(); U8T_data_L_temp=U8comdata; COM(); U8checkdata_temp=U8comdata; DATA=1; //数据校验 U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp); if(U8temp==U8checkdata_temp) { U8RH_data_H=U8RH_data_H_temp; U8RH_data_L=U8RH_data_L_temp; U8T_data_H=U8T_data_H_temp; U8T_data_L=U8T_data_L_temp; U8checkdata=U8checkdata_temp; } return 1; } else //传感器不响应 { return 0; } } /******************************************************************** * 文件名 : 液晶1602显示.c * 描述 : 该程序实现了对液晶1602的控制。 ***********************************************************************/ /******************************************************************** * 名称 : delay() * 功能 : 延时,延时时间大概为140US。 * 输入 : 无 * 输出 : 无 ***********************************************************************/ void delay() { int i,j; for(i=0; i<=10; i++) for(j=0; j<=2; j++); } /******************************************************************** * 名称 : enable(uchar del) * 功能 : 1602命令函数 * 输入 : 输入的命令值 * 输出 : 无 ***********************************************************************/ void write_1602com(uchar del) { P0 = del; RS = 0; E = 1; delay(); E = 0; delay(); } /******************************************************************** * 名称 : write(uchar del) * 功能 : 1602写数据函数 * 输入 : 需要写入1602的数据 * 输出 : 无 ***********************************************************************/ void write_1602dat(uchar del) { P0 = del; RS = 1; E = 1; delay(); E = 0; delay(); } /******************************************************************** * 名称 : L1602_init() * 功能 : 1602初始化,请参考1602的资料 * 输入 : 无 * 输出 : 无 ***********************************************************************/ void L1602_init(void) { write_1602com(0x38); write_1602com(0x0c); write_1602com(0x06); write_1602com(0x01); //清屏要放在最后 } //液晶显示 void display() { write_1602com(0x83); write_1602dat(temperature%100/10+0x30); write_1602dat(temperature%100%10+0x30); write_1602com(0x8c); write_1602dat(humidity%100/10+0x30); write_1602dat(humidity%100%10+0x30); write_1602com(0x80+0x40+3); // write_1602dat(PM_NUM%10000/1000+0x30); // write_1602dat('.'); // write_1602dat(PM_NUM%1000/100+0x30); write_1602dat(PM_NUM%100/10+0x30); write_1602dat(PM_NUM%10+0x30); write_1602com(0x85); write_1602dat(0xdf); } //设置液晶显示 void display_1() { write_1602com(0x83); write_1602dat(TH%100/10+0x30); write_1602dat(TH%100%10+0x30); write_1602com(0x8c); write_1602dat(TL%100/10+0x30); write_1602dat(TL%100%10+0x30); write_1602com(0xc3); write_1602dat(HH%100/10+0x30); write_1602dat(HH%100%10+0x30); write_1602com(0xcc); write_1602dat(HL%100/10+0x30); write_1602dat(HL%100%10+0x30); } //液晶字符串显示 void write_string(uchar * str) { while( * str) { write_1602dat(* str); str++; } } /***按键函数***/ void KEY() { if(K1==0) { Delay1(200); if(K1==0) { flag++; if(flag==1) { write_1602com(0x80); write_string("TH: C TL: C"); write_1602com(0xc0); write_string("HH: % HL: % "); write_1602com(0x85); write_1602dat(0xdf); write_1602com(0x8e); write_1602dat(0xdf); display_1(); write_1602com(0x84); write_1602com(0x0f); } else if(flag==2) write_1602com(0x8d); else if(flag==3) write_1602com(0xc4); else if(flag==4) write_1602com(0xcd); else if(flag==5) { write_1602com(0xc0); write_string(" "); write_1602com(0x80); write_string("Sg:00mg/m3 "); write_1602com(0x83); // write_1602dat(PM_H%10000/1000+0x30); // write_1602dat('.'); write_1602dat(PM_H/100+0x30); write_1602dat(PM_H%100/10+0x30); // write_1602dat('0'); write_1602com(0x87); } else { write_1602com(0x80); write_string("Te: C Hu: % "); write_1602com(0xc0); if(bufang==1) write_string("Sg:00mg/m3 "); else write_string("Sg:00mg/m3 "); write_1602com(0x85); write_1602dat(0xdf); display(); write_1602com(0x0c); flag=0; write_eeprom(); } while(!K1); } } if(K2==0) //按键+ { Delay1(200); if(K2==0) { switch (flag) { case 1: TH++;if(TH>99) TH=0;if(TH<=TL) TH=TL+1; write_1602com(0x83);write_1602dat(TH/10+0x30);write_1602dat(TH%10+0x30); write_1602com(0x84);break; case 2: TL++;if(TL>98) TL=0; if(TL>=TH) TL=TH-1; write_1602com(0x8c);write_1602dat(TL/10+0x30);write_1602dat(TL%10+0x30);write_1602com(0x8d); break; case 3: HH++;if(HH>99) HH=0; if(HH<=HL) HH=HL+1;write_1602com(0xc3);write_1602dat(HH/10+0x30);write_1602dat(HH%10+0x30); write_1602com(0xc4);break; case 4: HL++;if(HL>98) HL=0; if(HL>=HH) HL=HH-1; write_1602com(0xcc);write_1602dat(HL/10+0x30);write_1602dat(HL%10+0x30); write_1602com(0xcd);break; case 5: PM_H+=10;if(PM_H>=1000) PM_H=999; write_1602com(0x83);write_1602dat(PM_H/100+0x30);write_1602dat(PM_H%100/10+0x30);write_1602com(0x87); break; } while(!K2); } } if(K3==0) //按键减 { Delay1(200); if(K3==0) { switch (flag) { case 1: TH--;if(TH>99) TH=99; if(TH<=TL) TH=TL+1; write_1602com(0x83);write_1602dat(TH/10+0x30);write_1602dat(TH%10+0x30); write_1602com(0x84);break; case 2: TL--;if(TL>99) TL=98;if(TL>=TH) TL=TH-1; write_1602com(0x8c);write_1602dat(TL/10+0x30);write_1602dat(TL%10+0x30);write_1602com(0x8d); break; case 3: HH--;if(HH>99) HH=99; if(HH<=HL) HH=HL+1; write_1602com(0xc3);write_1602dat(HH/10+0x30);write_1602dat(HH%10+0x30); write_1602com(0xc4);break; case 4: HL--;if(HL>99) HL=98;if(HL>=HH) HL=HH-1; write_1602com(0xcc);write_1602dat(HL/10+0x30);write_1602dat(HL%10+0x30); write_1602com(0xcd);break; case 5: PM_H-=10;if(PM_H<=10) PM_H=10; write_1602com(0x83);write_1602dat(PM_H/100+0x30);write_1602dat(PM_H%100/10+0x30);write_1602com(0x87); break; } while(!K3); } } } /******************************************************************** * 名称 : Main() * 功能 : 主函数 ***********************************************************************/ void main() { uint testnum; Timer0_Init(); //定时器0初始化 RW=0; L1602_init(); write_1602com(0x85); write_1602dat(0xdf); write_1602com(0x80); write_1602dat('T'); display(); init_eeprom(); read_eeprom(); write_1602com(0x80); write_string("Te: C Hu: % "); write_1602com(0xc0); if(bufang==1) write_string("Sg:00mg/m3 B"); else write_string("Sg:00mg/m3 "); testnum = RH(); humidity = U8RH_data_H; //读出温湿度,只取整数部分 temperature = U8T_data_H; while(1) { if (FlagStartRH == 1) //温湿度转换标志检查 { testnum = RH(); FlagStartRH = 0; humidity = U8RH_data_H; //读出温湿度,只取整数部分 temperature = U8T_data_H; //以下都是判断是否报警亮对应的灯 if(temperature>=TH) LED2=0; else LED2=1; if(temperature<=TL) LED3=0; else LED3=1; if(humidity>=HH) LED4=0; else LED4=1; if(humidity<=HL) LED5=0; else LED5=1; } if(flag==0) display(); //液晶显示 KEY(); //按键检测 if(PM_NUM*10>=PM_H) //判断粉尘 LED1=0; else LED1=1; // 蜂鸣器判断 if(LED1==0||LED2==0||LED3==0||LED4==0||LED5==0||(LED6==0&&bufang==1)) flag_BJ=1; else { flag_BJ=0; alarm=1; } } } 帮我错这段代码nop_有错

/* * ADXL345模块 * * 用途:ADXL345模块IIC测试程序 * * 作者 日期 备注 * Huafeng Lin 2010/12/10 新增 * Huafeng Lin 2010/12/11 修改 * */ #include <REG51.H> #include <math.h> //Keil library #include <stdio.h> //Keil library #include <INTRINS.H> #define uchar unsigned char #define uint unsigned int #define DataPort P0 //LCD1602数据端口 sbit SCL=P1^7; //IIC时钟引脚定义 sbit SDA=P1^6; //IIC数据引脚定义 sbit LCM_RS=P2^6; //LCD1602命令端口 sbit LCM_RW=P2^5; //LCD1602命令端口 sbit LCM_EN=P2^7; //LCD1602命令端口 int step_count = 0; // 步数计数器 int last_step_state = 0; // 上一次的步态状态 int step_threshold = 1000; // 步态阈值,根据实际调试调整 #define SlaveAddress 0xA6 //定义器件在IIC总线中的从地址,根据ALT ADDRESS地址引脚不同修改 //ALT ADDRESS引脚接地时地址为0xA6,接电源时地址为0x3A typedef unsigned char BYTE; typedef unsigned short WORD; BYTE BUF[8]; //接收数据缓存区 uchar ge,shi,bai,qian,wan; //显示变量 int dis_data; //变量 void delay(unsigned int k); void InitLcd(); //初始化lcd1602 void Init_ADXL345(void); //初始化ADXL345 void WriteDataLCM(uchar dataW); void WriteCommandLCM(uchar CMD,uchar Attribc); void DisplayOneChar(uchar X,uchar Y,uchar DData); void conversion(uint temp_data); void Single_Write_ADXL345(uchar REG_Address,uchar REG_data); //单个写入数据 uchar Single_Read_ADXL345(uchar REG_Address); //单个读取内部寄存器数据 void Multiple_Read_ADXL345(); //连续的读取内部寄存器数据 //------------------------------------ void Delay5us(); void Delay5ms(); void ADXL345_Start(); void ADXL345_Stop(); void ADXL345_SendACK(bit ack); bit ADXL345_RecvACK(); void ADXL345_SendByte(BYTE dat); BYTE ADXL345_RecvByte(); void ADXL345_ReadPage(); void ADXL345_WritePage(); //----------------------------------- /*void StepCounter() { int current_step_state = 0; // 当前步态状态 // int z_data = (BUF[5] << 8) + BUF[4]; // 合成Z轴数据 step_count = (BUF[5] << 8) + BUF[4]; // 判断Z轴加速度是否超过阈值 // if (abs(z_data) > step_threshold) { // current_step_state = 1; // 当前状态为步态 // } else { // current_step_state = 0; // 当前状态非步态 // } // 判断是否为一步 if (current_step_state == 1 && last_step_state == 0) { // step_count++; // 步数加1 } // 更新上一次步态状态 last_step_state = current_step_state; } */ void DisplaySteps() { uchar ge, shi, bai, qian; // 个、十、百、千位变量 int temp = step_count; // 临时变量用于分解步数 ge = temp % 10; // 个位 temp /= 10; shi = temp % 10; // 十位 temp /= 10; bai = temp % 10; // 百位 temp /= 10; qian = temp % 10; // 千位 // 显示步数 DisplayOneChar(10, 0, 'S'); // 显示'S' DisplayOneChar(11, 0, 'T'); // 显示'T' DisplayOneChar(12, 0, 'E'); // 显示'E' DisplayOneChar(13, 0, 'P'); // 显示'P' DisplayOneChar(14, 0, 'S'); // 显示'S' DisplayOneChar(15, 0, ':'); // 显示':' DisplayOneChar(0, 1, qian + '0'); // 显示千位 DisplayOneChar(1, 1, bai + '0'); // 显示百位 DisplayOneChar(2, 1, shi + '0'); // 显示十位 DisplayOneChar(3, 1, ge + '0'); // 显示个位 } //********************************************************* void conversion(uint temp_data) { wan=temp_data/10000+0x30 ; temp_data=temp_data%10000; //取余运算 qian=temp_data/1000+0x30 ; temp_data=temp_data%1000; //取余运算 bai=temp_data/100+0x30 ; temp_data=temp_data%100; //取余运算 shi=temp_data/10+0x30 ; temp_data=temp_data%10; //取余运算 ge=temp_data+0x30; } /*******************************/ void delay(unsigned int k) { unsigned int i,j; for(i=0;i<k;i++) { for(j=0;j<121;j++) {;}} } /*******************************/ void WaitForEnable(void) { DataPort=0xff; LCM_RS=0;LCM_RW=1;_nop_(); LCM_EN=1;_nop_();_nop_(); while(DataPort&0x80); LCM_EN=0; } /*******************************/ void WriteCommandLCM(uchar CMD,uchar Attribc) { if(Attribc)WaitForEnable(); LCM_RS=0;LCM_RW=0;_nop_(); DataPort=CMD;_nop_(); LCM_EN=1;_nop_();_nop_();LCM_EN=0; } /*******************************/ void WriteDataLCM(uchar dataW) { WaitForEnable(); LCM_RS=1;LCM_RW=0;_nop_(); DataPort=dataW;_nop_(); LCM_EN=1;_nop_();_nop_();LCM_EN=0; } /***********************************/ void InitLcd() { WriteCommandLCM(0x38,1); WriteCommandLCM(0x08,1); WriteCommandLCM(0x01,1); WriteCommandLCM(0x06,1); WriteCommandLCM(0x0c,1); } /***********************************/ void DisplayOneChar(uchar X,uchar Y,uchar DData) { Y&=1; X&=15; if(Y)X|=0x40; X|=0x80; WriteCommandLCM(X,0); WriteDataLCM(DData); } /************************************** 延时5微秒(STC90C52RC@12M) 不同的工作环境,需要调整此函数,注意时钟过快时需要修改 当改用1T的MCU时,请调整此延时函数 **************************************/ void Delay5us() { _nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_(); } /************************************** 延时5毫秒(STC90C52RC@12M) 不同的工作环境,需要调整此函数 当改用1T的MCU时,请调整此延时函数 **************************************/ void Delay5ms() { WORD n = 560; while (n--); } /************************************** 起始信号 **************************************/ void ADXL345_Start() { SDA = 1; //拉高数据线 SCL = 1; //拉高时钟线 Delay5us(); //延时 SDA = 0; //产生下降沿 Delay5us(); //延时 SCL = 0; //拉低时钟线 } /************************************** 停止信号 **************************************/ void ADXL345_Stop() { SDA = 0; //拉低数据线 SCL = 1; //拉高时钟线 Delay5us(); //延时 SDA = 1; //产生上升沿 Delay5us(); //延时 } /************************************** 发送应答信号 入口参数:ack (0:ACK 1:NAK) **************************************/ void ADXL345_SendACK(bit ack) { SDA = ack; //写应答信号 SCL = 1; //拉高时钟线 Delay5us(); //延时 SCL = 0; //拉低时钟线 Delay5us(); //延时 } /************************************** 接收应答信号 **************************************/ bit ADXL345_RecvACK() { SCL = 1; //拉高时钟线 Delay5us(); //延时 CY = SDA; //读应答信号 SCL = 0; //拉低时钟线 Delay5us(); //延时 return CY; } /************************************** 向IIC总线发送一个字节数据 **************************************/ void ADXL345_SendByte(BYTE dat) { BYTE i; for (i=0; i<8; i++) //8位计数器 { dat <<= 1; //移出数据的最高位 SDA = CY; //送数据口 SCL = 1; //拉高时钟线 Delay5us(); //延时 SCL = 0; //拉低时钟线 Delay5us(); //延时 } ADXL345_RecvACK(); } /************************************** 从IIC总线接收一个字节数据 **************************************/ BYTE ADXL345_RecvByte() { BYTE i; BYTE dat = 0; SDA = 1; //使能内部上拉,准备读取数据, for (i=0; i<8; i++) //8位计数器 { dat <<= 1; SCL = 1; //拉高时钟线 Delay5us(); //延时 dat |= SDA; //读数据 SCL = 0; //拉低时钟线 Delay5us(); //延时 } return dat; } //******单字节写入******************************************* void Single_Write_ADXL345(uchar REG_Address,uchar REG_data) { ADXL345_Start(); //起始信号 ADXL345_SendByte(SlaveAddress); //发送设备地址+写信号 ADXL345_SendByte(REG_Address); //内部寄存器地址,请参考中文pdf22页 ADXL345_SendByte(REG_data); //内部寄存器数据,请参考中文pdf22页 ADXL345_Stop(); //发送停止信号 } //********单字节读取***************************************** uchar Single_Read_ADXL345(uchar REG_Address) { uchar REG_data; ADXL345_Start(); //起始信号 ADXL345_SendByte(SlaveAddress); //发送设备地址+写信号 ADXL345_SendByte(REG_Address); //发送存储单元地址,从0开始 ADXL345_Start(); //起始信号 ADXL345_SendByte(SlaveAddress+1); //发送设备地址+读信号 REG_data=ADXL345_RecvByte(); //读出寄存器数据 ADXL345_SendACK(1); ADXL345_Stop(); //停止信号 return REG_data; } //********************************************************* // //连续读出ADXL345内部加速度数据,地址范围0x32~0x37 // //********************************************************* void Multiple_read_ADXL345(void) { uchar i; ADXL345_Start(); //起始信号 ADXL345_SendByte(SlaveAddress); //发送设备地址+写信号 ADXL345_SendByte(0x32); //发送存储单元地址,从0x32开始 ADXL345_Start(); //起始信号 ADXL345_SendByte(SlaveAddress+1); //发送设备地址+读信号 for (i=0; i<6; i++) //连续读取6个地址数据,存储中BUF { BUF[i] = ADXL345_RecvByte(); //BUF[0]存储0x32地址中的数据 if (i == 5) { ADXL345_SendACK(1); //最后一个数据需要回NOACK } else { ADXL345_SendACK(0); //回应ACK } } ADXL345_Stop(); //停止信号 Delay5ms(); } //***************************************************************** //初始化ADXL345,根据需要请参考pdf进行修改************************ void Init_ADXL345() { Single_Write_ADXL345(0x31,0x0B); //测量范围,正负16g,13位模式 Single_Write_ADXL345(0x2C,0x08); //速率设定为12.5 参考pdf13页 Single_Write_ADXL345(0x2D,0x08); //选择电源模式 参考pdf24页 Single_Write_ADXL345(0x2E,0x80); //使能 DATA_READY 中断 Single_Write_ADXL345(0x1E,0x00); //X 偏移量 根据测试传感器的状态写入pdf29页 Single_Write_ADXL345(0x1F,0x00); //Y 偏移量 根据测试传感器的状态写入pdf29页 Single_Write_ADXL345(0x20,0x05); //Z 偏移量 根据测试传感器的状态写入pdf29页 } //*********************************************************************** //显示x轴 void display_x() { float temp; dis_data=(BUF[1]<<8)+BUF[0]; //合成数据 if(dis_data<0){ dis_data=-dis_data; DisplayOneChar(10,0,'-'); //显示正负符号位 } else DisplayOneChar(10,0,' '); //显示空格 temp=(float)dis_data*3.9; //计算数据和显示,查考ADXL345快速入门第4页 conversion(temp); //转换出显示需要的数据 DisplayOneChar(8,0,'X'); DisplayOneChar(9,0,':'); DisplayOneChar(11,0,qian); DisplayOneChar(12,0,'.'); DisplayOneChar(13,0,bai); DisplayOneChar(14,0,shi); DisplayOneChar(15,0,' '); } //*********************************************************************** //显示y轴 void display_y() { float temp; dis_data=(BUF[3]<<8)+BUF[2]; //合成数据 if(dis_data<0){ dis_data=-dis_data; DisplayOneChar(2,1,'-'); //显示正负符号位 } else DisplayOneChar(2,1,' '); //显示空格 temp=(float)dis_data*3.9; //计算数据和显示,查考ADXL345快速入门第4页 conversion(temp); //转换出显示需要的数据 DisplayOneChar(0,1,'Y'); //第1行,第0列 显示y DisplayOneChar(1,1,':'); DisplayOneChar(3,1,qian); DisplayOneChar(4,1,'.'); DisplayOneChar(5,1,bai); DisplayOneChar(6,1,shi); DisplayOneChar(7,1,' '); } //*********************************************************************** //显示z轴 void display_z() { float temp; dis_data=(BUF[5]<<8)+BUF[4]; //合成数据 if(dis_data<0){ dis_data=-dis_data; DisplayOneChar(10,1,'-'); //显示负符号位 } else DisplayOneChar(10,1,' '); //显示空格 temp=(float)dis_data*3.9; //计算数据和显示,查考ADXL345快速入门第4页 conversion(temp); //转换出显示需要的数据 if(qian!=0x30) { step_count++; } DisplayOneChar(8,1,'Z'); //第0行,第10列 显示Z DisplayOneChar(9,1,':'); DisplayOneChar(11,1,qian); DisplayOneChar(12,1,'.'); DisplayOneChar(13,1,bai); DisplayOneChar(14,1,shi); DisplayOneChar(15,1,' '); } //********************************************************* //******主程序******** //********************************************************* /*void main() { uchar devid; delay(500); //上电延时 InitLcd(); //液晶初始化ADXL345 DisplayOneChar(0,0,'A'); DisplayOneChar(1,0,'D'); DisplayOneChar(2,0,'X'); DisplayOneChar(3,0,'L'); DisplayOneChar(4,0,'3'); DisplayOneChar(5,0,'4'); DisplayOneChar(6,0,'5'); Init_ADXL345(); //初始化ADXL345 devid=Single_Read_ADXL345(0X00); //读出的数据为0XE5,表示正确 while(1) //循环 { Multiple_Read_ADXL345(); //连续读出数据,存储在BUF中 display_x(); //---------显示X轴 display_y(); //---------显示Y轴 display_z(); //---------显示Z轴 delay(200); //延时 } }*/ void main() { uchar devid; delay(500); // 上电延时 InitLcd(); // 液晶初始化ADXL345 DisplayOneChar(0,0,'A'); DisplayOneChar(1,0,'D'); DisplayOneChar(2,0,'X'); DisplayOneChar(3,0,'L'); DisplayOneChar(4,0,'3'); DisplayOneChar(5,0,'4'); DisplayOneChar(6,0,'5'); Init_ADXL345(); // 初始化ADXL345 devid=Single_Read_ADXL345(0X00); // 读出的数据为0XE5,表示正确 while(1) // 循环 { Multiple_Read_ADXL345(); // 连续读出数据,存储在BUF中 display_x(); // 显示X轴 display_y(); // 显示Y轴 display_z(); // 显示Z轴 // StepCounter(); // 步数统计 DisplaySteps(); // 显示步数 delay(200); // 延时 } } 帮我改下计数精度

///共用0104的板 #include <reg51.h> #include <math.h> #include <intrins.h> #include "ascii.h" #define uint unsigned int #define uchar unsigned char uchar i; //Define Key's Input #define AUTO 0x80 //P2^7: Input auto_run_id #define ADDU 0x40 //P2^6: Display picture UP to end #define SUBD 0x20 //P2^5: Display picture Down to begin #define ADUP 0x10 //P2^4: For COG module:adjust Register's value to add #define ADDN 0x08 //P2^3: For COG moduel:adjust Register's value to sub #define KEY_IN P2 ///******************************************************************************* #define v0 0x1B ///vo=[0.7+CT*0.005]/BIAS=5V #define bias 0x00 ////1/8 uint constr; //对比度调节 //Control the program to run #define BmpMax 5 uchar autoid; //Indicate that LCD display automatically uchar bmp_id; //The picture's id to display uchar dispid; //To reflash the display picture //------------------------------------------------------------------------- sbit SCLK = P1^3; //串行时钟 sbit SDA = P1^4; //串行数据输入 sbit RES = P1^1; /// sbit CS = P1^0; /// uchar code ch1[]={ 0X55,0X55,0X55,0X55,0X55,0X55,0X55,0X55,0X55,0X2F,0XFF,0XFF,0X4B,0X55,0X55,0X55, 0X40,0X55,0X55,0X55,0X55,0X55,0X55,0X55,0X55,0X55,0X2E,0XAA,0XAA,0X4B,0X55,0X55, 0X55,0X40,0X55,0X55,0X55,0X55,0X55,0X55,0X55,0X55,0X56,0X55,0X55,0X55,0XDF,0X55, 0X55,0X55,0X40,0X55,0X55,0X55,0X55,0X55,0X55,0X55,0X55,0X57,0X7E,0XAA,0XAA,0X95, 0X55,0X55,0X55,0X40,}; uchar code ch2[]={ 0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XA9,0XAA,0XAA,0XAA,0XFE,0XAA,0XAA,0XAA, 0X80,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAB,0XFA,0XAA,0XAA,0X6A,0XAA,0XAA, 0XAA,0X80,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XA9,0XAB,0XFF,0XFF,0XB4,0XAA, 0XAA,0XAA,0X80,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XD1,0X55,0X55,0X6A, 0XAA,0XAA,0XAA,0X80,}; uchar code ch3[]={ 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0X2B,0XFF,0XFF,0XDE,0X00,0X00,0X00, 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X7A,0XAA,0XAA,0X4A,0X00,0X00, 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X7B,0XFF,0XFF,0XDE,0X00, 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X7B,0XFF,0XFF,0XDE, 0X00,0X00,0X00,0X00,}; //------------------------------------------------------------------------- void delay_us(uchar dus) { uchar mm; for(mm=0;mm<dus;mm++) _nop_(); } //------------------------------------------------------------------------- void delay_ms(uint dms) { int mmm; for(mmm=0;mmm<dms;mmm++) { delay_us(250); } } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void wr_cmd(uchar wrcmd) { unsigned char ii,DA; SCLK=0; CS=0; _nop_(); SDA=0; //RS=0 SCLK=0; _nop_();_nop_();_nop_();_nop_(); SCLK=1; DA=wrcmd; for(ii=0;ii<8;ii++) { if((DA&0x80)==0x80) SDA=1; else SDA=0; SCLK=0; _nop_();_nop_();_nop_();_nop_(); SCLK=1; DA=DA<<1; } CS=1;_nop_(); } //----------------------------------------------------------------------------- void wr_data(uchar wrdata) { unsigned char ii,DA; SCLK=0; CS=0; _nop_(); SDA=1; SCLK=0; _nop_();_nop_();_nop_();_nop_(); SCLK=1; DA=wrdata; for(ii=0;ii<8;ii++) { if((DA&0x80)==0x80) SDA=1; else SDA=0; SCLK=0; _nop_();_nop_();_nop_();_nop_(); SCLK=1; DA=DA<<1; } CS=1;_nop_(); } ///******************************************************************** //----------------------------------------------------------------------------- void wr_cmd1(uchar wrcmd) { unsigned char ii,DA; SCLK=0; CS=1; _nop_(); SDA=0; //RS=0 SCLK=0; _nop_();_nop_();_nop_();_nop_(); SCLK=1; DA=wrcmd; for(ii=0;ii<8;ii++) { if((DA&0x80)==0x80) SDA=1; else SDA=0; SCLK=0; _nop_();_nop_();_nop_();_nop_(); SCLK=1; DA=DA<<1; } CS=1;_nop_(); } //----------------------------------------------------------------------------- void wr_data1(uchar wrdata) { unsigned char ii,DA; SCLK=0; CS=1; _nop_(); SDA=1; SCLK=0; _nop_();_nop_();_nop_();_nop_(); SCLK=1; DA=wrdata; for(ii=0;ii<8;ii++) { if((DA&0x80)==0x80) SDA=1; else SDA=0; SCLK=0; _nop_();_nop_();_nop_();_nop_(); SCLK=1; DA=DA<<1; } CS=1;_nop_(); } //------------------------------------------------------------------------- void init_lcd() { constr=v0; // autoid=1; // bmp_id=0; // dispid=1; // RES=1; delay_ms(10); RES=0; delay_ms(10); RES=1; delay_ms(10); wr_cmd(0x3A); //OSC ON wr_cmd(0x2f); //VD VS VC VF ON wr_cmd(0xB1); // Reference voltage select wr_cmd(0x1B); // wr_cmd(0xB2); //Frame Control wr_cmd(0x87); // LN 15~0 DIV number by inside oscillator ==600 wr_cmd(0x13); //150Hz wr_cmd(0x60); //display control COM1~COM4 SEG132~SEG1 REV=0 wr_cmd(0x34); //BIAS 1/6 100 wr_cmd(0x50); // Display start line COM0 wr_cmd(0x40); wr_cmd(0xA0); //SET DUTY wr_cmd(0x94); // 1/4 DUTY wr_cmd(0x3D); //Display on wr_cmd(0x88); wr_cmd(0x88); wr_cmd(0x88); wr_cmd(0x88); wr_cmd(0x60); //set com pad map sequence wr_cmd(0xe3); delay_ms(10); } //------------------------------------------------------------------------ //------------------------------------------------------------------------- void disp_all() //全显 { uchar jj,ii; for(ii=0;ii<4;ii++) { wr_cmd(0x10); //set AY(row)Address wr_cmd(0x00+ii); wr_cmd(0xc0); //set AX address for(jj=0;jj<17;jj++) wr_data(0xff); } } //------------------------------------------------------------------------- void disp_off() //CLEAR SCREEN { uchar jj,ii; for(ii=0;ii<4;ii++) { wr_cmd(0x10); //set AY(row)Address wr_cmd(0x00+ii); wr_cmd(0xc0); //set AX address for(jj=0;jj<17;jj++) wr_data(0x00); } } //------------------------------------------------------------------------- void disp_CSB() //CLEAR SCREEN { uchar jj,ii; for(ii=0;ii<4;ii++) { wr_cmd1(0x10); //set AY(row)Address wr_cmd1(0x00+ii); wr_cmd1(0xc0); //set AX address for(jj=0;jj<17;jj++) wr_data1(0x00); } } //------------------------------------------------------------------------- void disp_checker1() // { uchar jj,ii; for(ii=0;ii<4;ii++) { wr_cmd(0x10); //set AY(row)Address wr_cmd(0x00+ii); wr_cmd(0xc0); //set AX address for(jj=0;jj<17;jj++) wr_data(ch1[jj+ii*17]); } } //------------------------------------------------------------------------- void disp_checker2() // { uchar jj,ii; for(ii=0;ii<4;ii++) { wr_cmd(0x10); //set AY(row)Address wr_cmd(0x00+ii); wr_cmd(0xc0); //set AX address for(jj=0;jj<17;jj++) wr_data(ch2[jj+ii*17]); } } //------------------------------------------------------------------------- void disp_checker3() // { uchar jj,ii; for(ii=0;ii<4;ii++) { wr_cmd(0x10); //set AY(row)Address wr_cmd(0x00+ii); wr_cmd(0xc0); //set AX address for(jj=0;jj<17;jj++) wr_data(ch3[jj+ii*17]); } } //---------------------------------------------------------------------------- void constr1() { wr_cmd(0xB1); // Reference voltage select wr_cmd(constr); // } //----------------------------------------------------------------------------- void do_key() { uchar tkeyin; KEY_IN=0xff; delay_ms(5); tkeyin=KEY_IN; //判断自动刷新标志 if((tkeyin&AUTO)==0x00) autoid=1; else autoid=0; //画面往下翻bmp_id++ if((tkeyin&ADDU)==0x00) { dispid=1; //刷新标志置"1" bmp_id++; if(bmp_id>=BmpMax) bmp_id=0; } //画面往上翻bmp_id-- if((tkeyin&SUBD)==0x00) { dispid=1; //刷新标志置"1" if(bmp_id>0) { bmp_id--; } else bmp_id=BmpMax-1; } //对比度参数constr++ if((tkeyin&ADUP)==0x00) { if(constr<127) constr++; constr1(); delay_ms(10); } //对比度参数constr-- if((tkeyin&ADDN)==0x00) { if(constr>0) constr--; constr1(); delay_ms(10); } delay_ms(50); } //------------------------------------------------------------------------- void main() { init_lcd(); disp_off(); // clear SCREEN delay_ms(10); while(1) { do_key(); if(dispid==1) { switch(bmp_id) { case 0: //全显画面 disp_all(); break; case 1: //方框画面 disp_off(); break; case 2: //正显象棋板 disp_checker1(); break; case 3: //负显象棋板 disp_checker2(); break; case 4: //负显象棋板 disp_checker3(); break; default: break; } dispid=0; //清除刷新标志 } if(autoid==1) { dispid=1; bmp_id++; if(bmp_id>=BmpMax) bmp_id=0; delay_ms(360); //自动显示时延时dl0 } } } 帮我把这个8051程序改为 stm32f1版本的

大家在看

recommend-type

Xilinx ISE rs_decoder_ipcore and encoder License

Xilinx ISE RS编码解码IP核的License
recommend-type

毕业设计&课设-一个基于Matlab的PET仿真和重建框架,具有系统矩阵的分析建模,能够结合各种数据….zip

matlab算法,工具源码,适合毕业设计、课程设计作业,所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答! matlab算法,工具源码,适合毕业设计、课程设计作业,所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答! matlab算法,工具源码,适合毕业设计、课程设计作业,所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答! matlab算法,工具源码,适合毕业设计、课程设计作业,所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答! matlab算法,工具源码,适合毕业设计、课程设计作业,所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答! matlab算法,工具源码,适合毕业设计、课程设计作业,所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随
recommend-type

MATLAB机械臂简单控制仿真(Simulink篇-总).zip

MATLAB下机器人可视化与控制---simulink篇中的简单例子,在Simulink中做了预定义轨迹的运动和Slider Gain控制的运动,用GUI控制的关节代码在MATLAB下机器人可视化与控制
recommend-type

使用 GCC 构建 STM23F0 ARM 项目的模板源码

使用 GCC 构建 STM23F0 ARM 项目的模板源码,具体请看 README
recommend-type

详细说明 VC++的MFC开发串口调试助手源代码,包括数据发送,接收,显示制式等29782183com

详细说明 VC++的MFC开发串口调试助手源代码,包括数据发送,接收,显示制式等29782183com

最新推荐

recommend-type

计算机网络学习中学员常见问题与改进方法

计算机网络学习中学员常见问题与改进方法+
recommend-type

基于高斯混合模型(GMM)和主成分分析(PCA)的疲劳语音识别.zip

1.版本:matlab2014a/2019b/2024b 2.附赠案例数据可直接运行。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
recommend-type

Java毕业设计基于SpringBoot+Vue开发的智慧农业系统源码+数据库(高分项目)

Java毕业设计基于SpringBoot+Vue开发的智慧农业系统源码+数据库(高分项目),个人大四的毕业设计、经导师指导并认可通过的高分设计项目,评审分99分,代码完整确保可以运行,小白也可以亲自搞定,主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。 Java毕业设计基于SpringBoot+Vue开发的智慧农业系统源码+数据库(高分项目)Java毕业设计基于SpringBoot+Vue开发的智慧农业系统源码+数据库(高分项目)Java毕业设计基于SpringBoot+Vue开发的智慧农业系统源码+数据库(高分项目)Java毕业设计基于SpringBoot+Vue开发的智慧农业系统源码+数据库(高分项目)Java毕业设计基于SpringBoot+Vue开发的智慧农业系统源码+数据库(高分项目)Java毕业设计个人大四的毕业设计、经导师指导并认可通过的高分设计项目,评审分99分,代码完整确保可以运行,小白也可以亲自搞定,主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。个人大四的毕业设计 收起
recommend-type

用bp神经网络预测油田产量

资源下载链接为: https://pan.quark.cn/s/82cb66f4d6b4 用bp神经网络预测油田产量(最新、最全版本!打开链接下载即可用!)
recommend-type

美国国际航空交通数据分析报告(1990-2020)

根据给定的信息,我们可以从中提取和分析以下知识点: 1. 数据集概述: 该数据集名为“U.S. International Air Traffic data(1990-2020)”,记录了美国与国际间航空客运和货运的详细统计信息。数据集涵盖的时间范围从1990年至2020年,这说明它包含了长达30年的时间序列数据,对于进行长期趋势分析非常有价值。 2. 数据来源及意义: 此数据来源于《美国国际航空客运和货运统计报告》,该报告是美国运输部(USDOT)所管理的T-100计划的一部分。T-100计划旨在收集和发布美国和国际航空公司在美国机场的出入境交通报告,这表明数据的权威性和可靠性较高,适用于政府、企业和学术研究等领域。 3. 数据内容及应用: 数据集包含两个主要的CSV文件,分别是“International_Report_Departures.csv”和“International_Report_Passengers.csv”。 a. International_Report_Departures.csv文件可能包含了以下内容: - 离港航班信息:记录了各航空公司的航班号、起飞和到达时间、起飞和到达机场的代码以及国际地区等信息。 - 航空公司信息:可能包括航空公司代码、名称以及所属国家等。 - 飞机机型信息:如飞机类型、座位容量等,这有助于分析不同机型的使用频率和趋势。 - 航线信息:包括航线的起始和目的国家及城市,对于研究航线网络和优化航班计划具有参考价值。 这些数据可以用于航空交通流量分析、机场运营效率评估、航空市场分析等。 b. International_Report_Passengers.csv文件可能包含了以下内容: - 航班乘客信息:可能包括乘客的国籍、年龄、性别等信息。 - 航班类型:如全客机、全货机或混合型航班,可以分析乘客运输和货物运输的比例。 - 乘客数量:记录了各航班或航线的乘客数量,对于分析航空市场容量和增长趋势很有帮助。 - 飞行里程信息:有助于了解国际间不同航线的长度和飞行距离,为票价设置和燃油成本分析提供数据支持。 这些数据可以用于航空客运市场分析、需求预测、收益管理等方面。 4. 数据分析和应用实例: - 航空流量分析:通过分析离港航班数据,可以观察到哪些航线最为繁忙,哪些机场的国际航空流量最大,这有助于航空公司调整航班时刻表和运力分配。 - 市场研究:乘客数据可以揭示不同国家和地区之间的人口流动趋势,帮助航空公司和政府机构了解国际旅行市场的需求变化。 - 飞机利用率:结合飞机机型和飞行频率信息,可以对特定机型的使用率进行分析,评估飞机维护需求和燃油效率。 - 安全监管:通过对比不同航空公司和航班的安全记录,监管机构可以更有效地评估航空公司的安全性能,并采取必要的监管措施。 5. 技术和方法论: 分析此类数据通常涉及数据清洗、数据整合、统计分析、时间序列分析、预测建模等数据科学方法。使用Excel、SQL、R、Python等工具进行数据处理和分析是常见的做法。例如,可以使用Python的Pandas库来清洗和准备数据,使用Matplotlib和Seaborn库来可视化数据,然后利用Scikit-learn或Statsmodels库来构建预测模型。 通过以上知识点的提取和分析,我们可以理解到“U.S. International Air Traffic data(1990-2020)-数据集”的重要性,它不仅记录了跨越30年的航空交通数据,还为各种分析和应用提供了详实的基础信息。对于航空业从业者、政策制定者、研究人员以及数据分析师来说,这是一个极具价值的数据资源。
recommend-type

统计学视角:深入理解最小二乘法的概率论基础

# 1. 最小二乘法的基本概念 最小二乘法(Least Squares Method, LSM)是统计学和数据分析中广泛使用的一种数学优化技术。其主要目的是通过最小化误差的平方和来寻找数据的最佳函数匹配。这种方法最早由高斯提出,但在工程、物理、经济和其他领域中有着广泛的应用。 在本章中,我们将首先了
recommend-type

vscode中使用Codeium

<think>好的,我需要回答用户如何在VSCode中使用Codeium插件的问题。首先,我需要回顾用户提供的引用内容,看看是否有相关信息。用户提供的引用[1]提到了Codeium Chat可以解释代码中的问题,引用[2]提到了在IDEA中的一些问题,可能对VSCode的安装有帮助。用户还提到了安装步骤、基本功能、常见问题等。 首先,我应该分步骤说明安装过程,包括在VSCode扩展商店搜索Codeium并安装。然后,登录部分可能需要用户访问仪表板获取API密钥,引用[2]中提到登录问题,可能需要提醒用户注意网络或权限设置。 接下来是基本功能,比如代码自动补全和Chat功能。引用[1]提到C
recommend-type

UniMoCo:统一框架下的多监督视觉学习方法

在详细解析“unimoco”这个概念之前,我们需要明确几个关键点。首先,“unimoco”代表的是一种视觉表示学习方法,它在机器学习尤其是深度学习领域中扮演着重要角色。其次,文章作者通过这篇论文介绍了UniMoCo的全称,即“Unsupervised, Semi-Supervised and Full-Supervised Visual Representation Learning”,其背后的含义是在于UniMoCo框架整合了无监督学习、半监督学习和全监督学习三种不同的学习策略。最后,该框架被官方用PyTorch库实现,并被提供给了研究者和开发者社区。 ### 1. 对比学习(Contrastive Learning) UniMoCo的概念根植于对比学习的思想,这是一种无监督学习的范式。对比学习的核心在于让模型学会区分不同的样本,通过将相似的样本拉近,将不相似的样本推远,从而学习到有效的数据表示。对比学习与传统的分类任务最大的不同在于不需要手动标注的标签来指导学习过程,取而代之的是从数据自身结构中挖掘信息。 ### 2. MoCo(Momentum Contrast) UniMoCo的实现基于MoCo框架,MoCo是一种基于队列(queue)的对比学习方法,它在训练过程中维持一个动态的队列,其中包含了成对的负样本。MoCo通过 Momentum Encoder(动量编码器)和一个队列来保持稳定和历史性的负样本信息,使得模型能够持续地进行对比学习,即使是在没有足够负样本的情况下。 ### 3. 无监督学习(Unsupervised Learning) 在无监督学习场景中,数据样本没有被标记任何类别或标签,算法需自行发现数据中的模式和结构。UniMoCo框架中,无监督学习的关键在于使用没有标签的数据进行训练,其目的是让模型学习到数据的基础特征表示,这对于那些标注资源稀缺的领域具有重要意义。 ### 4. 半监督学习(Semi-Supervised Learning) 半监督学习结合了无监督和有监督学习的优势,它使用少量的标注数据与大量的未标注数据进行训练。UniMoCo中实现半监督学习的方式,可能是通过将已标注的数据作为对比学习的一部分,以此来指导模型学习到更精准的特征表示。这对于那些拥有少量标注数据的场景尤为有用。 ### 5. 全监督学习(Full-Supervised Learning) 在全监督学习中,所有的训练样本都有相应的标签,这种学习方式的目的是让模型学习到映射关系,从输入到输出。在UniMoCo中,全监督学习用于训练阶段,让模型在有明确指示的学习目标下进行优化,学习到的任务相关的特征表示。这通常用于有充足标注数据的场景,比如图像分类任务。 ### 6. PyTorch PyTorch是一个开源机器学习库,由Facebook的人工智能研究团队开发,主要用于计算机视觉和自然语言处理等任务。它被广泛用于研究和生产环境,并且因其易用性、灵活性和动态计算图等特性受到研究人员的青睐。UniMoCo官方实现选择PyTorch作为开发平台,说明了其对科研社区的支持和对易于实现的重视。 ### 7. 可视化表示学习(Visual Representation Learning) 可视化表示学习的目的是从原始视觉数据中提取特征,并将它们转换为能够反映重要信息且更易于处理的形式。在UniMoCo中,无论是无监督、半监督还是全监督学习,最终的目标都是让模型学习到有效的视觉表示,这些表示可以用于下游任务,如图像分类、目标检测、图像分割等。 ### 8. 标签队列(Label Queue) UniMoCo通过标签队列维护受监管的标签,这可能意味着对于那些半监督或全监督学习的任务,模型在进行对比学习时,会参考这些来自标签队列的数据。标签队列机制能帮助模型更好地利用有限的标注数据,增强模型的泛化能力。 ### 结论 UniMoCo的提出,以及其官方PyTorch实现的发布,将对计算机视觉领域产生深远影响。它不仅提供了一个统一的对比学习框架,使得从无监督到全监督的学习过程更加灵活和高效,而且为研究者们提供了一个强力的工具,以便更好地探索和实现各种视觉任务。UniMoCo的研究和应用前景,为机器学习尤其是深度学习在视觉领域的研究和实践提供了新的视角和可能。
recommend-type

【MATLAB算法精讲】:最小二乘法的实现与案例深度分析

# 1. 最小二乘法的基本原理 最小二乘法是一种数学优化技术,它通过最小化误差的平方和来寻找数据的最佳函数匹配。其核心思想是选择一条曲线,使得所有观察点到这条曲线的距离之和最小。这种方法广泛应用于统计学、信号处理、工程学和经济学等领域,尤其适用于需要通过一组数据点来确定函数参数的情况。 ## 1.1 统计学视角下的最小二乘法 在统计学中,最小二乘法经常用于
recommend-type

Idea使用教程+jdk配置

<think>好的,我现在需要回答用户关于IntelliJ IDEA使用教程和JDK配置方法的问题。首先,用户明确提到了参考站内引用中的内容,引用[1]和引用[2]都涉及JDK的配置步骤,但看起来这些引用内容可能来自其他问题或文档,可能与当前问题不完全相关,但用户希望我利用这些信息来组织回答。 首先,我需要确认IntelliJ IDEA配置JDK的基本步骤,并整合用户提供的引用内容。引用[1]提到选择JDK安装根目录,例如D:\develop\Java\jdk-17,这说明配置时需要定位到JDK的主目录。引用[2]则提到了通过New按钮选择JDK版本,并完成项目创建,这部分可能涉及到项目设置