标题:谁会这段程序帮我讲解一下,分全给你们了!!!
只看楼主
弟大勿勃
Rank: 2
等 级:论坛游民
帖 子:186
专家分:59
注 册:2014-4-17
结帖率:81.82%
已结贴  问题点数:80 回复次数:5 
谁会这段程序帮我讲解一下,分全给你们了!!!
程序代码:
#include "reg51.h"
#include "absacc.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
sbit IR=P3^2;//红外接口标志
uchar irtime;//红外用全局变量
uchar IRcord[4];
uchar irdata[33];
uchar num;
bit irpro_ok,irok;

uchar G_sj,Y_sj,R_sj,count=0;
bit SN_Pass;
bit EW_Pass;

//uchar R_sj_T,R_sj_T;
uchar digit,Szsj[2],Key_count;

/*管脚定义*/
sbit CLK =P2^0;//MAX7219的时钟
sbit DIN =P2^1;//MAX7219的串行数据
sbit LOAD=P2^2;//MAX7219的片选
sbit EW_G=P0^0;//东西绿   
sbit EW_Y=P0^1;//东西黄    
sbit EW_R=P0^2;//东西红
sbit SN_G=P0^3;//南北绿    
sbit SN_Y=P0^4;//南北黄    
sbit SN_R=P0^5;//南北红   
     
/*MAX7219寄存器*/
#define NoOp   0x00                //空操作寄存器
#define Digit0 0x01                //数码管1寄存器
#define Digit1 0x02                //数码管2寄存器
#define Digit2 0x03                //数码管3寄存器    
#define Digit3 0x04                //数码管4寄存器
#define Digit4 0x05                //数码管5寄存器
#define Digit5 0x06                //数码管6寄存器
#define Digit6 0x07                //数码管7寄存器
#define Digit7 0x08                //数码管8寄存器

#define DecodeMode      0x09       //译码模式寄存器
#define Intensity       0x0a       //亮度寄存器
#define ScanLimit       0x0b       //扫描位数寄存器
#define ShutDown        0x0c       //低功耗模式寄存器
#define DisplayTest     0x0f       //显示测试寄存器
#define ShutdownMode    0x00       //低功耗方式
#define NormalOperation 0x01       //正常操作方式

#define ScanDigit      0x07        //扫描位数设置,显示8位数码管
#define DecodeDigit    0xff        //译码设置,8位均为BCD码
#define IntensityGrade 0x0a        //亮度级别设置
#define TestMode       0x01        //显示测试模式
#define TextEnd        0x00        //显示测试结束,恢复正常工作模式
void delay(uint t);
void SendChar(uchar ch);
void WriteWord(uchar addr,uchar num);
void Init_MAX7219(void);

/*液晶1602口地址*/
#define wr_com XBYTE[0xC000]    //写命令
#define wr_data XBYTE[0xC100]   //写数据
#define rd_com XBYTE[0xC200]    //读命令
#define rd_data XBYTE[0xC300]   //读数据
void Delay_lcd(uint n);
void lcd_init(void);//lcd初始化
void write_cmd(uchar cmd);//lcd写命令
void write_string(uchar *s);//写字符串
void write_data(uchar dat) ;//写数据
void set_display_place(uchar line,uchar column);
void write_string_lcd(uchar line,uchar column,uchar *string);

void Ircordpro(void);
void Hw_Scan(void);
void Ir_work(void);
void digit_deal(void);

void Delay_lcd(uint n)
{
  uint x;
  while(n--)
  {
    x=500;
    while(x--);
  }
}
/*向LCD输入指令*/
void write_cmd(uchar cmd)
{
  uchar dl;
  do 
  {
    dl=rd_com;
  }  
    while((dl&0x80)!=0);//判忙
  wr_com=cmd;
  Delay_lcd(1);
}
/*向LCD写入数据*/
void write_data(uchar dat)
{
  uchar dl;
  do 
  {
    dl=rd_com;
  }   
    while((dl&0x80)!=0);//判忙
  wr_data=dat;
  Delay_lcd(1);
}
/*向LCD写入字符串*/
void write_string(uchar *s)
{
  while(*s!='\0')//'\0'字符串结束标志位
  {
    write_data(*s);
    s++;
  }
}
/*设置字符显示位置*/
void set_display_place(uchar line,uchar column)
{
  uchar address;
  if(line==1)
  {
    address=0x80+column;
  }
  else if(line==2)
  {
    address=0xc0+column;
  }
  write_cmd(address);
}
/*将字符串显示在LCD特定位置*/
void write_string_lcd(uchar line,uchar column,uchar *string)
{
  set_display_place(line,column);
  write_string(string);
  Delay_lcd(1);
}
/*LCD初始化*/
void lcd_init(void)
{
  write_cmd(0x38);
  write_cmd(0x06);
  write_cmd(0x0c);
  write_cmd(0x01);
}

void delay(uint t)
{
  uint i;
  while(t--){for(i=0;i<125;i++){}}
}
/*向MAX7219写入字节(8位)*/
void SendChar(uchar ch)
{
  uchar i,temp;
  _nop_();
  for(i=0;i<8;i++)
  {
    temp=ch&0x80;ch=ch<<1;
    if(temp) {DIN=1;CLK=0;CLK=1;}
    else     {DIN=0;CLK=0;CLK=1;}
  }
}
/*向MAX7219写入字(16位)*/
void WriteWord(uchar addr,uchar num)
{
  LOAD=0;
  _nop_();SendChar(addr);
  _nop_();SendChar(num);
  _nop_();
  LOAD=1;//锁存进相应寄存器
}
/*初始化MAX7219*/
void Init_MAX7219(void)
{
  WriteWord(DecodeMode,DecodeDigit);  //设置译码模式       0x09,0xff
  WriteWord(Intensity,IntensityGrade);//设置亮度           0x0a,0x0a
  WriteWord(ScanLimit,ScanDigit);     //设置扫描界限       0x0b,0x07
  WriteWord(ShutDown,NormalOperation);//设置为正常工作模式 0x0c,0x01
}

void write_sj(uchar add,uchar num)
{
  uchar shi,ge;
  shi=num/10;ge=num%10;
  WriteWord(add,shi);WriteWord(add+1,ge);
}
 

/*红外码值处理*/
void Ircordpro(void)//红外码值处理函数
{ 
  uchar i,j,k;
  uchar cord,value;
  k=1;
  for(i=0;i<4;i++)//处理4个字节
  {
    for(j=1;j<=8;j++)//处理1个字节8位
    {
      cord=irdata[k];
      if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
      value|=0x80;
      if(j<8) {value>>=1;} k++;
    }
    IRcord[i]=value; value=0;     
  } 
  irpro_ok=1;//处理完毕标志位置1
}
/*红外扫描*/
void Hw_Scan(void)
{
  if(irok)//如果接收好了进行红外处理
  {   
    Ircordpro();irok=0;
  }
  if(irpro_ok)//如果处理好后进行工作处理,如按对应的按键后显示对应的数字等
  {
    Ir_work();
  }
}
void Ir_work(void)
{
  switch(IRcord[2])
  {
    case 0x45: EW_Pass=1;SN_Pass=0;break;//先东西通行
    case 0x46: EW_Pass=0;SN_Pass=0;break;//停止按键  
    case 0x47: EW_Pass=0;SN_Pass=1;break;//先南北通行
      
    case 0x44: ;break;
    case 0x40: ;break;

    case 0x43: ;break;
    case 0x07: ;break;//加1按键
    case 0x15: ;break;//减0按键

    case 0x09: ;break; 
//                if(Key_count==2)
//                {
//                  R_sj=10*Szsj[0]+Szsj[1];                                                                             
//
//                  set_display_place(2,4);
//                  write_data(R_sj/10+0x30);
//                  write_data(R_sj%10+0x30);
//                  
//                }Key_count=0; 
//    
                
    case 0x19: ;break;
    case 0x0d: ;break;

    case 0x16: digit=0;break;//数字0键
    case 0x0C: digit=1;break;//数字1键   
    case 0x18: digit=2;break;//数字2键    
      case 0x5E: digit=3;break;//数字3键
    case 0x08: digit=4;break;//数字4键
    case 0x1C: digit=5;break;//数字5键
    case 0x5A: digit=6;break;//数字6键
    case 0x42: digit=7;break;//数字7键
    case 0x52: digit=8;break;//数字8键
    case 0x4A: digit=9;break;//数字9键        
    default:   break; 
  }
  irpro_ok=0;
}

//void digit_deal(void)
//{
//  if(Key_count<2)
//  {              
//    Szsj[Key_count]=digit;
//    Key_count++;             
//  }  
//}
/*外部中断0初始化*/
void EX0init(void)//外部中断0初始化
{
  IT0=1;//指定外部中断0下降沿触发,INT0(P3.2)
  EX0=1;//使能外部中断
  EA=1;//开总中断
}
void Init_Time0(void)
{
  TMOD=0X12;//定时器T0工作方式2,TH0是重装值,TL0是初值;定时器T1工作方式1
  TH0=0x00;//重载值
  TL0=0x00;//初始化值
  ET0=1;//打开定时器T0中断
  TR0=1;//启动定时器T0 
}
void Init_Time1(void)
{
  TMOD=0X12;//定时器T0工作方式2,TH0是重装值,TL0是初值;定时器T1工作方式1
  TH1=(65536-46083)/256;
  TL1=(65536-46083)%256;
  ET1=1;//打开定时器T1中断
  TR1=1;//启动定时器T1 
}
void main()
{

  lcd_init();
  Init_MAX7219();                 //MAX7219初始化 
  WriteWord(DisplayTest,TestMode);//开始显示测试,点亮所有LED 0x0f,0x01
  SN_G=0;SN_Y=0;SN_R=0;EW_G=0;EW_Y=0;EW_R=0;
  delay(3000);                       //延时约3s
  WriteWord(DisplayTest,TextEnd); //退出显示测试模式          0x0f,0x00
  SN_G=1;SN_Y=1;SN_R=1;EW_G=1;EW_Y=1;EW_R=1;
  
  G_sj=15;Y_sj=5;R_sj=20;
  Init_Time0();
  Init_Time1();
  EX0init();

  while(1)
  {
    //digit_deal();
    Hw_Scan();
  }
}
void EX0_ISR() interrupt 0 //外部中断0服务函数
{
  static uchar i;//接收红外信号处理
  static bit startflag;//是否开始处理标志位
  if(startflag)                         
  {
    if(irtime<63&&irtime>=33)//引导码 TC9012的头码,头吗是9ms+4.5ms和4.5ms+4.5ms均可
    i=0;irdata[i]=irtime;//头码存储到0位,存储每个电平的持续时间,用于以后判断是0还是1
    irtime=0;i++;//调到下一位
       if(i==33) { irok=1;i=0;}//表示存储32位完毕
  }
  else { irtime=0;startflag=1;}//装回初值,有其他干扰使为0
} 
//T0中断服务程序
void Time0() interrupt 1 using 1 
{
  irtime++;//用于计数2个下降沿之间的时间
}
//T1中断服务程序
void Time1() interrupt 3 
{
  TH1=(65536-46083)/256;
  TL1=(65536-46083)%256;
  count++;
  if(count==20)
  {
    count=0;

    if(EW_Pass==1)//东西通行
    {
      R_sj--;write_sj(7,R_sj);write_sj(3,R_sj);
      if(R_sj>=5)
      {
        G_sj--;write_sj(5,G_sj);write_sj(1,G_sj);SN_G=1;SN_Y=1;SN_R=0;EW_G=0;EW_Y=1;EW_R=1;
        if(G_sj==0) {G_sj=15;}  
      }
      else 
      {
        Y_sj--;write_sj(5,Y_sj);write_sj(1,Y_sj);SN_G=1;SN_Y=1;SN_R=0;EW_G=1;EW_Y=0;EW_R=1;
        if(Y_sj==0) {Y_sj=5;}
      }
      if(R_sj==0) {R_sj=20;EW_Pass=0;SN_Pass=1;}      
    }
    if(SN_Pass==1)//南北通行
    {
      R_sj--;write_sj(5,R_sj);write_sj(1,R_sj);
      if(R_sj>=5)
      {
        G_sj--;write_sj(7,G_sj);write_sj(3,G_sj);SN_G=0;SN_Y=1;SN_R=1;EW_G=1;EW_Y=1;EW_R=0;
        if(G_sj==0) {G_sj=15;}  
      }
      else 
      {
        Y_sj--;write_sj(7,Y_sj);write_sj(3,Y_sj);SN_G=1;SN_Y=0;SN_R=1;EW_G=1;EW_Y=1;EW_R=0;
        if(Y_sj==0) {Y_sj=5;}
      }
      if(R_sj==0) {R_sj=20;SN_Pass=0;EW_Pass=1;}      
    }
  }
}
搜索更多相关主题的帖子: include count 接口 include count 接口 
2015-06-01 10:59
弟大勿勃
Rank: 2
等 级:论坛游民
帖 子:186
专家分:59
注 册:2014-4-17
得分:0 
2015-06-02 19:14
tlliqi
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:204
帖 子:15453
专家分:65956
注 册:2006-4-27
得分:80 
不懂
2015-06-02 22:28
星属仑
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2016-2-19
得分:0 
怎么看着像是交通信号灯啊?
2016-02-26 22:54
q913794286
Rank: 1
等 级:新手上路
帖 子:19
专家分:0
注 册:2017-4-27
得分:0 
7219是8位数码管驱动芯片,穿行数据输入。程序太简单,表示不想解释。
2017-04-27 08:21
yjf314400
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2019-3-31
得分:0 
2019-07-16 15:16



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-446052-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.201771 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved