这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » caipengxiang MCU开发板DIY 进程更贴

共4条 1/1 1 跳转至

caipengxiang MCU开发板DIY 进程更贴

助工
2012-01-10 13:07:25     打赏

//用开发板制作的一个计算器实验
//下面是源代码,

#include<reg52.h>
#include<stdlib.h>
#include<stdio.h>
#define LCD_DATA P0       //lcd数据显示
#define LCD_KEY  P2        //键盘接口
#define uchar unsigned char
#define uint  unsigned int

sbit LCD_RS=P1^0;   // LCD 1602的RS 接口  
sbit LCD_RW=P1^1;  //LCD 1602的RW 接口
sbit LCD_E=P1^2;      //LCD 1602的E使能端接口

//是否有按键按下
bit  isKeyPress;
//按键所选择键值          
uchar  selectKey;
//记录连续输入数字的个数  
uchar  count;   
//记录连续接收到的数字,最多输入14位
uchar  receivedData[14];
//记录存储结果
long result;
//输入数据暂存
long rectmp1,rectmp2; 
//记录输入符号
uchar sign;

 

//定时器0
void Timer0();
//LCD初始化     
void lcdInit();
//LCD写数据       
void lcdWriteData(uchar dat);
//LCD写命令     
void lcdWriteCommand(uchar com);
//最小延时1ms时参数为1    
void delay1ms();      
//键盘扫描程序 
uchar scanKeyboard();
//将字符写入第Y行第x个位置 
void displayCharAt(uchar x,uchar y,uchar dat);  
//显示字符串在指定的位置 
void displayStringAt(uchar x,uchar y,uchar *str); 
//在当前字符的下一个位置显示字符
void displayChar(uchar dat);      
//在当前字符的下一个位置显示字符串
void displayString(uchar *str); 
//处理从键盘得到的按键值
void keyProcess(uchar key);
//清除LCD中的所有显示,并将光标至于地址0      
void clearDisplay();
//将字符串转换成整形
uint stringToInt(uchar *str);
//复位
void lcdReset();


//在指定位置显示字符 
void displayCharAt(uchar x,uchar y,uchar dat)
{
 uchar address;
 if(y==1)
         address=0x80+x;
 else
         address=0xc0+x;
 lcdWriteCommand(address);
 lcdWriteData(dat);
}

void displayChar(uchar dat)
{
 lcdWriteData(dat);
}
//在指定位置显示字符串
void displayStringAt(uchar x,uchar y,uchar *str)
{
  uchar address;
    uchar i;
 if(y==1)
         address=0x80+x;
 else
         address=0xc0+x;
 for(i=0;str[i]!='\0';i++)
 {

 //  lcdWriteCommand(address++);
  lcdWriteData(str[i]);
 }
}

void displayString(uchar *str)
{
    uchar i;
 for(i=0;str[i]!='\0';i++)
  lcdWriteData(str[i]);
}
void lcdInit()     //lcd初始化函数

 uchar i;

 count=0;
 selectKey=0;
 isKeyPress=0;
 result=0;
 rectmp1=0;
 rectmp2=0;
 sign=' ';  //空格表示没有输入符号
 for(i=0;i<14;i++)
  receivedData[i]='\0';

    lcdWriteCommand(0x38);//设置8位格式,2行,5x7
  lcdWriteCommand(0x0C);//整体显示,关光标,不闪烁
    lcdWriteCommand(0x06);//设定输入方式,增量不移位
    lcdWriteCommand(0x01);//清除屏幕显示
  delay1ms();
}

void lcdWriteData(uchar dat)    //lcd写数据
{
 LCD_RS=1;  //写数据
 LCD_RW=0;
 LCD_E=0;
 LCD_DATA=dat;
 LCD_E=1;
 delay1ms();
 LCD_E=0;
 delay1ms();
}

void lcdWriteCommand(uchar com)    //lcd写命令
{
 LCD_RS=0;  //写命令
 LCD_RW=0;
 LCD_E=0;
 LCD_DATA=com;
 LCD_E=1;
 delay1ms();
 LCD_E=0;
 delay1ms();
}
uchar scanKeyboard()      //键盘扫描程序
{
     uchar  tmp1,tmp2,key;
      LCD_KEY=0XFe;        //第一行
      tmp1=LCD_KEY;
   tmp2=tmp1&0xf0;
      if(tmp2!=0xf0)
      {
           delay1ms();               //键抖动处理
           tmp1=LCD_KEY;
           if((tmp1&0xf0)==tmp2)
           {
                switch(tmp2)
                {
                  case 0xe0:key='7';break;
                  case 0xd0:key='8';break;
                  case 0xb0:key='9';break;
                  case 0x70:key=0xfd;break;  //0xfd除号在1602液晶中的代码
                }
                while(tmp2!=0xf0)  //键释放处理
                {
                  tmp2=LCD_KEY;
      tmp2=tmp2&0xf0;
                }
                isKeyPress=1;     //键按标志置1
                return(key);
           }
      }


      LCD_KEY=0XFd;        //第二行
      tmp1=LCD_KEY;
   tmp2=tmp1&0xf0;
      if(tmp2!=0xf0)
      {
           delay1ms();               //键抖动处理
           tmp1=LCD_KEY;
           if((tmp1&0xf0)==tmp2)
           {
                switch(tmp2)
                {
                  case 0xe0:key='4';break;
                  case 0xd0:key='5';break;
                  case 0xb0:key='6';break;
                  case 0x70:key='*';break;  //乘号
                }
                while(tmp2!=0xf0)  //键释放处理
                {
                  tmp2=LCD_KEY;
      tmp2=tmp2&0xf0;
                }
                isKeyPress=1;     //键按标志置1
                return(key);
           }
      }

   LCD_KEY=0XFb;        //第三行
      tmp1=LCD_KEY;
   tmp2=tmp1&0xf0;
      if(tmp2!=0xf0)
      {
           delay1ms();               //键抖动处理
           tmp1=LCD_KEY;
           if((tmp1&0xf0)==tmp2)
           {
                switch(tmp2)
                {
                  case 0xe0:key='1';break;
                  case 0xd0:key='2';break;
                  case 0xb0:key='3';break;
                  case 0x70:key='-';break;  //减号
                }
                while(tmp2!=0xf0)  //键释放处理
                {
                  tmp2=LCD_KEY;
      tmp2=tmp2&0xf0;
                }
                isKeyPress=1;     //键按标志置1
                return(key);
           }
      }

   LCD_KEY=0XF7;        //第四行
      tmp1=LCD_KEY;
   tmp2=tmp1&0xf0;
      if(tmp2!=0xf0)
      {
           delay1ms();               //键抖动处理
           tmp1=LCD_KEY;
           if((tmp1&0xf0)==tmp2)
           {
                switch(tmp2)
                {
                  case 0xe0:key='c';break;
                  case 0xd0:key='0';break;
                  case 0xb0:key='=';break;
                  case 0x70:key='+';break;  //
                }
                while(tmp2!=0xf0)  //键释放处理
                {
                  tmp2=LCD_KEY;
      tmp2=tmp2&0xf0;
                }
                isKeyPress=1;     //键按标志置1
                return(key);
           }
      }
  return(0);
}

void delay1ms()
{
    uchar a,b;
    for(b=199;b>0;b--)
        for(a=1;a>0;a--);
}

void keyProcess(uchar key)
{
  if('0'<=key&&key<='9')
  {
   if(count==0)
  { 
   uchar i;
  // clearDisplay();
   for(i=0;i<14;i++)
    receivedData[i]='\0';  
  }
 // if(count==14)  //溢出则显示错误
 //  displayString(" data is limited ");
   displayChar(key); //显示输入字符
  receivedData[count]=key;
  count++;
  }
  else if(key=='+'||key=='-'||key=='*'||key==0xfd)
  { 
   uchar i;
  if(receivedData[0]!='\0')
    rectmp1=atol(receivedData);
  sign=key;

  count=0;
//  clearDisplay();
  displayChar(key);
  for(i=0;i<14;i++)
   receivedData[i]='\0';
  }
  else if(key=='=')
  {
   
   char buf[10];
  uint i;
  clearDisplay();
   rectmp2=atol(receivedData);
  switch(sign)
  {
  case '+':    //加
   rectmp1+=rectmp2;
   break;
  case '-':    //减
   rectmp1-=rectmp2;
   break;
  case '*':    //乘
   rectmp1*=rectmp2;
   break;
  case 0xfd:    //除
   rectmp1/=rectmp2;
   break;
  }
   
  //将计算结果转化成字符串
  sprintf(buf,"%ld",rectmp1);  
   displayString(buf);
  count=0;
  for(i=0;i<14;i++)
   receivedData[i]='\0'; 
  }
  else if(key=='c')
  {
  lcdReset();    //复位
  } 
}


//复位
void lcdReset()
{
 lcdInit(); 
}
//清除LCD中的所有显示,并将光标至于地址0 
void clearDisplay()
{
 lcdWriteCommand(0x01);
 lcdWriteCommand(0x80);
}
void Timer0() interrupt 1
{
    TH0 = 0x3C;
    TL0 = 0x0B0;
}
void main()
{
  lcdInit();
  
     TMOD = 0x01;  //定时器0,方式1
     TH0 = 0x3C;   //50us,晶振频率为12M
     TL0 = 0x0B0;
     EA = 1;    //允许溢出中断设置
     ET0 = 1;
     TR0 = 1;   //开始计时
  while(1)
  {
   selectKey=scanKeyboard();
   if(selectKey!=0)
   {
    keyProcess(selectKey);
   }
    
  }

}   




关键词: caipengxiang     开发     进程     更贴     显示         

助工
2012-01-10 13:15:49     打赏
2楼
由于没有照相机,只好给大家展示用PROTUES仿真的电路图了。
本来还有一个科学计算器的程序,但由于本人使用那个程序在参加
另外一个活动,暂时不能公开那个功能强大的程序。待那个活动完结了
以后再将它贴上来。那个程序对于单片机的初学者来说有一定的难度,
如果能看懂并且能加以改进的话就说明单片机已经到了一定的水平了。



助工
2012-01-10 13:17:08     打赏
3楼

再加上一句,那个程序有2000多行的代码,装到单片机里有20k的程序


菜鸟
2012-01-28 15:56:41     打赏
4楼

共4条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]