[问答] 传感器单片机仿真

[复制链接]

实习生

发表于 2018-1-12 17:46:49   149 查看 0 回复 来自手机 显示全部楼层 倒序浏览
分享
为什么lcd的灯只亮不显示
#include<reg51.h>
#include<intrins.h>
#include <absacc.h>
#include <math.h>

#define uchar unsigned char
#define uint   unsigned int
#define BUSY  0x80                               //常量定义
#define DATAPORT P0


//ADC0832的引脚
sbit ADCS =P3^5;  //ADC0832 chip seclect
sbit ADDI =P3^7;  //ADC0832 k in
sbit ADDO =P3^7;  //ADC0832 k out
sbit ADCLK =P3^6;  //ADC0832 clock signal

sbit LCM_RS=P2^0;
sbit LCM_RW=P2^1;
sbit LCM_EN=P2^2;

uchar ad_data;                                    //采样值存储
sbit Alarm_led_red =P1^5;                         //超过压力表量程最大值红色led报警定义
sbit Alarm_led_green=P1^6;                        //低于压力表量程最小值绿色led报警定义
                         //adc采样值存储单元
char press_data;                                  //标度变换存储单元
unsigned char ad_alarm;                           //报警值存储单元
unsigned char press_bai=0;                        //显示值百位
unsigned char press_shi=0;                        //显示值十位
unsigned char press_ge=0;                         //显示值个位
unsigned char press_dot=0;                        //显示值十分位

uchar code str0[]={"Press:    .  kpa "};
uchar code str1[]={" Check BY Jack "};

void delay(uint);
void lcd_wait(void);
void delay_LCM(uint);             ​​​​​​​​​​​//LCD延时子程序
void initLCM( void);               ​​​​​​​​​​​//LCD初始化子程序
void lcd_wait(void);              ​​​​​​​​​​​//LCD检测忙子程序
void WriteCommandLCM(uchar WCLCM,uchar BusyC);                              //写指令到ICM子函数
void WriteDataLCM(uchar WDLCM);                                             //写数据到LCM子函数
void DisplayOneChar(uchar X,uchar Y,uchar DData);                           //显示指定坐标的一个字符子函数
void DisplayListChar(uchar X,uchar Y,uchar code *DData);                    //显示指定坐标的一串字符子函数
void display(void);                                                         //系统显示子函数
uchar Adc0832(unsigned char channel);​​​​​​​​​​​​​​​
void alarm(void);
void data_pro(void);


/**********main funcation************/

void main(void)
{
   delay(500);                      //系统延时500ms启动
//​ad_data=0;                       //采样值存储单元初始化为0
  ​initLCM( );
      
  ​WriteCommandLCM(0x01,1);​​    //清显示屏
   DisplayListChar(0,0,str0);
  ​DisplayListChar(0,1,str1);

​while(1)
   {
​   ad_data =Adc0832(0);​   //采样值存储单元初始化为0
​  
​    alarm();

​​data_pro();
​​
​​display();
​​​​
​}
}


/*********延时K*1ms,12.000mhz**********/

void delay(uint k)
{
   uint i,j;
   for(i=0;i<k;i++)
   {
       for(j=0;j<60;j++)
       ​{;}
   }
}  
/**********写指令到ICM子函数************/

void WriteCommandLCM(uchar WCLCM,uchar BusyC)
{
   if(BusyC)lcd_wait();
​DATAPORT=WCLCM;
   LCM_RS=0;                   // 选中指令寄存器
   LCM_RW=0;               ​// 写模式​
   LCM_EN=1;   
​_nop_();  
​_nop_();
​_nop_();
   LCM_EN=0;

}

/**********写数据到LCM子函数************/

void WriteDataLCM(uchar WDLCM)
{
   lcd_wait( );             //检测忙信号   
​DATAPORT=WDLCM;
   LCM_RS=1;                // 选中数据寄存器
   LCM_RW=0;           ​ // 写模式
   LCM_EN=1;
   _nop_();
​_nop_();
​_nop_();
   LCM_EN=0;
}

/***********lcm内部等待函数*************/

void lcd_wait(void)
{
   DATAPORT=0xff;​     //读LCD前若单片机输出低电平,而读出LCD为高电平,则冲突,Proteus仿真会有显示逻辑黄色
​LCM_EN=1;
   LCM_RS=0;  
   LCM_RW=1;  
   _nop_();
   _nop_();
​_nop_();
   while(DATAPORT&BUSY)  
​{  LCM_EN=0;
​   _nop_();
​   _nop_();
​   LCM_EN=1;
​   _nop_();
​   _nop_();
​   }​
  ​LCM_EN=0;​

}

/**********LCM初始化子函数***********/

void initLCM( )
{  
​DATAPORT=0;​
​delay(15);
​WriteCommandLCM(0x38,0);    //三次显示模式设置,不检测忙信号
   delay(5);
   WriteCommandLCM(0x38,0);
   delay(5);
   WriteCommandLCM(0x38,0);
   delay(5);

   WriteCommandLCM(0x38,1);    //8bit数据传送,2行显示,5*7字型,检测忙信号
   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;               //若y为1(显示第二行),地址码+0X40
   X|=0x80;                    //指令码为地址码+0X80
   WriteCommandLCM(X,0);
   WriteDataLCM(DData);
}

/*******显示指定坐标的一串字符子函数*****/

void DisplayListChar(uchar X,uchar Y,uchar code *DData)
{
   uchar ListLength=0;
   Y&=0x01;
   X&=0x0f;
   while(X<16)
   {
       DisplayOneChar(X,Y,DData[ListLength]);
       ListLength++;
       X++;
   }
}

/*****************系统显示子函数*****************/

void display(void)
{
  ​WriteCommandLCM(0x0c,1);    ​​​​//显示屏打开,光标不显示,不闪烁,检测忙信号​
​DisplayListChar(0,0,str0);​
​DisplayListChar(0,1,str1);​


​DisplayOneChar(7,0,press_bai+0x30);
​DisplayOneChar(8,0,press_shi+0x30);
​DisplayOneChar(9,0,press_ge +0x30);
   DisplayOneChar(11,0,press_dot+0x30);
​delay(1000);                               //稳定显示
}
/************
读ADC0832函数
************/

//采集并返回
uchar Adc0832(unsigned char channel)     //AD转换,返回结果
{
   uchar i=0;
   uchar j;
   uint dat=0;
   uchar ndat=0;

   if(channel==0)channel=2;
   if(channel==1)channel=3;
   ADDI=1;
   _nop_();
   _nop_();
   ADCS=0;//拉低CS端
   _nop_();
   _nop_();
   ADCLK=1;//拉高CLK端
   _nop_();
   _nop_();
   ADCLK=0;//拉低CLK端,形成下降沿1
   _nop_();
   _nop_();
   ADCLK=1;//拉高CLK端
   ADDI=channel&0x1;
   _nop_();
   _nop_();
   ADCLK=0;//拉低CLK端,形成下降沿2
   _nop_();
   _nop_();
   ADCLK=1;//拉高CLK端
   ADDI=(channel>>1)&0x1;
   _nop_();
   _nop_();
   ADCLK=0;//拉低CLK端,形成下降沿3
   ADDI=1;//控制命令结束
   _nop_();
   _nop_();
   dat=0;
   for(i=0;i<8;i++)
   {
       dat|=ADDO;//收数据
       ADCLK=1;
       _nop_();
       _nop_();
       ADCLK=0;//形成一次时钟脉冲
       _nop_();
       _nop_();
       dat<<=1;
       if(i==7)dat|=ADDO;
   }  
   for(i=0;i<8;i++)
   {
       j=0;
       j=j|ADDO;//收数据
       ADCLK=1;
       _nop_();
       _nop_();
       ADCLK=0;//形成一次时钟脉冲
       _nop_();
       _nop_();
       j=j<<7;
       ndat=ndat|j;
       if(i<7)ndat>>=1;
   }
   ADCS=1;//拉低CS端
   ADCLK=0;//拉低CLK端
   ADDO=1;//拉高数据端,回到初始状态
   dat<<=8;
   dat|=ndat;
   return(dat);            //return ad k
}


void data_pro(void)
{
     unsigned int temp;
     float  press;​   ​​  

​  if(14<ad_data<243)​​​               //当压力值介于15kpa到115kpa之间时,遵循线性变换
​ ​{​​​   
​​    int vary=ad_data;​​​​​​//y=(115-15)/(243-13)*X+15kpa​​​
​​​press=((10.0/23.0)*vary)+9.3;​​​//测试时补偿值为9.3
​​​​​​​​​​​​​​  
​​​temp=(int)(press*10);​                //放大10倍,便于后面的计算
​   ​​​​​​​​​    ​
​​    ​​​​​​​​​​​
​​​press_bai=temp/1000;​​​     ​//取压力值百位
​​​press_shi=(temp%1000)/100;​​    ​//取压力值十位
​​​press_ge=((temp%1000)%100)/10;​    ​//取压力值个位
​​​press_dot=((temp%1000)%100)%10;​​​//取压力值十分位

​   ​   }​   
​​​
}
/*****************报警子函数*******************/

void alarm(void)
{
​ if(ad_data>=243)                           //如果当前压力值大于115kpa,

         {  Alarm_led_red=0; }                 //则启动报警
      
​  else
​     {​  Alarm_led_red=1; }​​        //关闭报警
      
}
高级模式
您需要登录后才可以回帖 登录 | 注册

关闭

站长推荐 上一条 /7 下一条

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

推荐专区

技术干货集中营

专家问答

用户帮助┃咨询与建议┃版主议事

工程师杂谈

工程师创意

工程师职场

论坛电子赛事

社区活动专版

发烧友活动

-

嵌入式论坛

ARM技术论坛

Android论坛

Linux论坛

单片机/MCU论坛

FPGA|CPLD|ASIC论坛

DSP论坛

嵌入式系统论坛

-

电源技术论坛

电源技术论坛

无线充电技术

-

硬件设计论坛

PCB设计论坛

电路设计论坛

电子元器件论坛

控制|传感

总线技术|接口技术

-

测试测量论坛

LabVIEW论坛

Matlab论坛

测试测量技术专区

仪器仪表技术专区

-

EDA设计论坛

multisim论坛

PADS技术论坛

Protel|AD|DXP论坛

Allegro论坛

proteus论坛|仿真论坛

EasyEDA-中国人自已的EDA工具

Orcad论坛

-

综合技术与应用

电机控制

智能电网

光电及显示

参考设计中心

汽车电子技术论坛

医疗电子论坛

-

开源硬件

-

无线通信论坛

无线通信技术专区

天线|RF射频|微波|雷达技术

-

IC设计论坛

芯片测试与失效分析

Mixed Signal/SOC[数模混合芯片设计]

Analog/RF IC设计

设计与制造封装测试

-

厂商专区

TI论坛

TI Deyisupport社区

-

检测技术与质量

电磁兼容(EMC)设计与整改

安规知识论坛

检测与认证

-

消费电子论坛

手机技术论坛

平板电脑/mid论坛

音视/视频/机顶盒论坛

-

电子论坛综合区

聚丰众筹官方社区

新人报道区

聚丰供应链

-

论坛服务区

-

供求信息发布

供需广告

招聘┃求职发布区

电子展览展会专区