找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 948|回复: 6
打印 上一主题 下一主题
收起左侧

关于测量PM2.5并在LCD上显示,同时实现串口通讯,大概功能就这样,有一个报错,死...

[复制链接]
跳转到指定楼层
楼主
//***************************************
// 空气质量测试仪设计
// 使用单片机STC90C516RD
// 晶振:11.0592M
// 显示:1602液晶显示//编程思路:
//简单的就是做一个1ms的定时中断(要准点可以定时时间减少,反之定时时间加大)
//在中断中检测IO口的电平,是低就 加1
//1s内总共检测1000次 ,检测累加的值除以10就是百分数,也就是低脉冲率。
//****************************************
#include"Reg52.H"                                           /* 调用MCS51寄存器头文件 */
#include"intrins.H"
#include "LCD1602.H"
#include"stdio.h"
#include <string.h>  

#define uc unsigned char   
#define uint unsigned int
        
typedef unsigned char  U8;       /* defined for unsigned 8-bits integer variable           无符号8位整型变量  */
typedef signed   char  S8;       /* defined for signed 8-bits integer variable                  有符号8位整型变量  */
typedef unsigned int   U16;      /* defined for unsigned 16-bits integer variable           无符号16位整型变量 */
typedef signed   int   S16;      /* defined for signed 16-bits integer variable           有符号16位整型变量 */
typedef unsigned long  U32;      /* defined for unsigned 32-bits integer variable           无符号32位整型变量 */
typedef signed   long  S32;      /* defined for signed 32-bits integer variable           有符号32位整型变量 */
typedef float          F32;      /* single precision floating point variable (32bits) 单精度浮点数(32位长度) */
typedef double         F64;      /* double precision floating point variable (64bits) 双精度浮点数(64位长度) */

unsigned char sChar_i=0;//写入数据sChar指针
unsigned char  sendFlag = 0;        //未发送数据时
unsigned char  receFlag =0;                //未接受到数据时  
//*********************************************
//MON51必须用到的
code unsigned char stop[3] _at_ 0x3b;
//*********************************************
sbit   PWM=P1^0;              //脉冲输出//xin//
sbit LED=P3^7;
U16    number_t0=0;                    
U16    lt_time=0;                         //低脉冲时间                     
U16    Temp0=0;   //低脉冲率

uc sChar[50]={'\0'};


void sendChar(unsigned char sendValue);  //发送一字节数据
void sendAll(unsigned char *pValue);       //发送一组数据
  //   


//*********************定时器T0用于定时1MS********
timer0() interrupt 1 using 1      //T/C0中断服务程序, 每1ms中断一次
{  

   number_t0++;
   if(PWM==0)  lt_time++;          //每1ms检测PWM脉冲是否为低电平     
   if(number_t0==1000)            //munber_t0计数到1000MS,即1S,计算低脉冲率
     { TR0=0;                      //关闭定时器0
           Temp0=(int)(lt_time/10);    //计算低脉冲率
           number_t0=0;                //1S时间计数器和低脉冲率变量初始化为0,开始下一个测量周期
           lt_time=0;
           TR0=1;                      // 启动定时器0
         }
   TH0=0xfc;
   TL0=0x66;
}
//
void dingshi()
{        TMOD=0x01;
   TH0=0xfc;                                            /*晶振:11.0592MHz,定时1ms*/
   TL0=0x66;
   ET0=1;
   TR0=1;
   EA=1;
   DelayMs( 200 );          /* 上电延时 */
}

//xin//
void initSer()//初始化  
{  
     TMOD=0x20;    //定时器工作方式,选择了定时器1,工作方式2 八位初值自动重装的8位定时器。         
     TH1=0xfd;     //定时器1初值  ,设置波特率为9600 配合为晶振11.0529MHZ,晶振的电容是20uf?  
     TL1=0xfd;  
     TR1=1;        //开启定时器1  

     SM0=0;             //属于SCON寄存器
     SM1=1;        //串口工作方式1,10位异步接收,(8位数据)波特率可变  
     REN=1;        //允许串行口接收位  
     EA=1;         //允许中断(总闸)  
     ES=1;         //允许串口中断
}  
void sendChar(unsigned char Value)                        //发送一个字节数据
{
         SBUF = Value;     
         sendFlag = 1;                                                        //设置发送标志位,发一字节就置位
         while(sendFlag);                                                //直到发完数据,将sendFlag清零后,才退出sendChar函数
}

void sendAll(unsigned char *pValue)                        //发送一组数据
{
        while((*pValue) != '\0')                                   //如果没有发送完毕就继续发
        {
                sendChar(*pValue);                              //发送1字节数据
                pValue++;                                                   //指向下1个字节
        }
}   
void serInt() interrupt 4  //中断函数
{  
        //TI——发送中断bai标志位,可寻址标志位。方式0时,发送完第8位数据后,由硬件置位,其它方式下,在发送或停止位之前由硬件置位,因此,TI=1表示帧发送结束,TI可由软件清“0”。
        //RI——接收中断标志位.可寻址标志位。接收完第8位数据后,该位由硬件置位,在其他工作方式下,该位由硬件置位,RI=1表示帧接收完成。
        //在串口中断处理时,TI,RI都需要软件清"0",硬件置位后不可能自动清0,此外,在进行缓冲区操作时,需要ES=0,以防止中断出现。
         if(RI)                                                               //接收数据,手动将RI清0  
     {         
                RI=0;
                if(SBUF=='\0'||SBUF=='#')
                {
                        sChar[sChar_i++]='\0';
                        receFlag=1;                                                        //修改接受标志,便于主函数进入while中发数据
                }
                else
                {
                        sChar[sChar_i++]=SBUF;                                //每次接受8位,存在SBUF里,转存到数组中
                }
     }  
     if(TI)                                                             //发送数据  
     {
                TI = 0;                                                                //发送完一个数据
                sendFlag = 0;                                                //清标志位
     }      
}  
//
//***********************主程序****************************
void main()
{  U8 DisplayBuf[16];  
                                       /* 存储转换后的数据 */
   dingshi();               
         initSer();  //xin                                 /* 上电延时 */
   LCD1602_Init();

   LCD1602_WriteUSerCode();                             /* 写入用户自定义字符 */
   LCD1602_SetDisplayPosition(0,1);                     /* 显示显示位置 */
   LCD1602_WriteString("Air quality test");

  while(1)                                              /*循环*/
  {                 
                sprintf(DisplayBuf," low rate=%3d",Temp0);             /*显示低脉冲率*/
    LCD1602_SetDisplayPosition(0,2);                        /* 显示显示位置 */
    LCD1602_WriteString(DisplayBuf);                        
               
                if(receFlag)  
                {
                        LED=~LED;
                        sChar_i=0;//接受数组指针归0,以便以下次接受
                        sendAll(sChar);
                        if(strlen(sChar)==4&&sChar[0]=='L'&&sChar[1]=='E'&&sChar[2]=='D')
                        {
                                 P1=sChar[3];
                        }              
                        receFlag=0;  
             }  
             if(sendFlag)                          //发送完毕之后,在电脑端输出。  
             {  
                 TI=1;                             //printf之前必须将T1置为1才行。  
                 while(!TI);
                 sendFlag=0;
             }
  }
}


1.png (202.53 KB, 下载次数: 32)

1.png
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:992336 发表于 2021-12-17 05:35 | 只看该作者
这个报错不正常,#include"intrins.H" 移到第一行试试,或者换一个keil 版本
回复

使用道具 举报

板凳
ID:442241 发表于 2021-12-19 14:42 | 只看该作者
0x0A 发表于 2021-12-17 05:35
这个报错不正常,#include"intrins.H" 移到第一行试试,或者换一个keil 版本

改了,还是报错
回复

使用道具 举报

地板
ID:517466 发表于 2021-12-19 15:15 | 只看该作者
这行不需要吧。使用_nop_的地方,直接引入这个函数所在的头文件不就可以么?是不是其他地方的错误导致的?
回复

使用道具 举报

5#
ID:517466 发表于 2021-12-19 15:16 | 只看该作者
你先把引用其它文件的地方注释掉,只编译自己的主程序,看看有没有问题。但一个个放开编译,确定出问题的文件所在
回复

使用道具 举报

6#
ID:442241 发表于 2021-12-19 15:21 | 只看该作者
0x0A 发表于 2021-12-17 05:35
这个报错不正常,#include"intrins.H" 移到第一行试试,或者换一个keil 版本

换了KEIL4在编译,就不报错了。非常感谢。
回复

使用道具 举报

7#
ID:517466 发表于 2021-12-19 15:26 | 只看该作者
intrins.h是系统底层的东西,不会有错。报出这个错误,基本上可以断定是你自已的程序代码出了问题,你试试排除法找错误点。很可能就是一个语句少了";"之类的错误
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表