×
嵌入式 > 技术百科 > 详情

单片机C语言程序举例(一)

发布时间:2020-06-20 发布时间:
|
本着共同学习,共同进步的目的,把我搞到的资料不辞辛苦的发上来,供初学者参考,希望可以对大家有帮助!所有程序是本人买 www.doflye.cn 上海浩豚电子科技的开发板赠送的。

1.流水灯C程序

 

#include
////////////////////////////////////////////////////////
void delay(unsigned int cnt) //简单的延时
{
 while(--cnt);
}
///////////////////////////////////////////////////////
main()
{
 P1=0xfe;//给初始化值
 while(1)
      {
    delay(30000);//delay at crystal frequency in 12MHz
    P1<<=1;//左移一位
    P1|=0x01;//最后一位补1
    if(P1==0x7f)//检测是否移到最左端?
          {
       delay(30000);//delay
          P1=0xfe;
          }
      }
}

2.数码管动态扫描C程序

 

#include

unsigned char const dofly[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值01234567
unsigned char code seg[]={0,1,2,3,4,5,6,7};//分别对应相应的数码管点亮
////////////////////////////////////////////////////////
void delay(unsigned int cnt)
{
 while(--cnt);
}
///////////////////////////////////////////////////////
main()
{
 unsigned char i;

 while(1)
      {
 
       P0=dofly[i];//取显示数据
    P2=seg[i];  //取段码
    delay(200); //扫描间隙延时
    i++;
    if(8==i)    //检测8位扫描完全?
      i=0;
      }
}
3.LED
/\/\
\  /
  \/点阵C程序

 

#include

unsigned char const dofly[]={0x00,0x6C,0x92,0x82,0x44,0x28,0x10,0x00};// 心的形状
unsigned char code seg[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//分别对应相应的段亮
////////////////////////////////////////////////////////
void delay(unsigned int cnt)
{
 while(--cnt);
}
///////////////////////////////////////////////////////
main()
{
 unsigned char i;

 while(1)
      {
 
       P0=dofly[i];//取显示数据
    P2=seg[i];  //取段码
    delay(200); //扫描间隙延时
    i++;
    if(8==i)
      i=0;
      }
}

4.实时时钟RTC

#include
#include

sbit SCK=P3^6;  
sbit SDA=P3^4;  
sbit RST = P3^5;   // DS1302复位

bit ReadRTC_Flag;

unsigned char l_tmpdate[7]={0,0,12,15,5,3,8};//秒分时日月周年08-05-15 12:00:00
unsigned char l_tmpdisplay[8];
code unsigned char write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分时日月周年 最低位读写位
code unsigned char read_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; 

code unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};
            //共阴数码管 0-9  '-' '熄灭‘表
code unsigned char table1[]={0,1,2,3,4,5,6,7};
                     //显示位码表

            
void Write_Ds1302_byte(unsigned char temp);
void Write_Ds1302( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302 ( unsigned char address );

void Read_RTC(void);//read RTC
void Set_RTC(void); //set RTC

void InitTIMER0(void);//inital timer0

void main(void)   
{
    InitTIMER0();
  Set_RTC();
 while(1){
  if(ReadRTC_Flag)
  {
     ReadRTC_Flag=0;
  Read_RTC();
  switch (l_tmpdate[0]/5)   //设计每个5秒交替显示年月日 时分秒
  {
  case 0:
  case 2:
  case 4:
  case 6:
  case 8:
  case 10:
   l_tmpdisplay[0]=l_tmpdate[2]/16;   //数据的转换,因我们采用数码管0~9的显示,将数据分开
   l_tmpdisplay[1]=l_tmpdate[2]&0x0f;
   l_tmpdisplay[2]=10;          //加入"-"
   l_tmpdisplay[3]=l_tmpdate[1]/16;
   l_tmpdisplay[4]=l_tmpdate[1]&0x0f;
   l_tmpdisplay[5]=10;
   l_tmpdisplay[6]=l_tmpdate[0]/16;
   l_tmpdisplay[7]=l_tmpdate[0]&0x0f; 
   break;
  case 1:
  case 3:
  case 5:
  case 7:
  case 9:
  case 11:
   l_tmpdisplay[0]=l_tmpdate[6]/16;
   l_tmpdisplay[1]=l_tmpdate[6]&0x0f;
   l_tmpdisplay[2]=10;
   l_tmpdisplay[3]=l_tmpdate[4]/16;
   l_tmpdisplay[4]=l_tmpdate[4]&0x0f;
   l_tmpdisplay[5]=10;
   l_tmpdisplay[6]=l_tmpdate[3]/16;
   l_tmpdisplay[7]=l_tmpdate[3]&0x0f;
   break;
  default:
   break;
  }
 
  }
 }
}

void InitTIMER0(void)
{
 TMOD|=0x01;//定时器设置 16位
 TH0=0xef;//初始化值
 TL0=0xf0;
 ET0=1;
 TR0=1;
 EA=1;
}

 

void Write_Ds1302_Byte(unsigned  char temp)
{
 unsigned char i;
 for (i=0;i<8;i++)      //循环8次 写入数据
  {
   SCK=0;
     SDA=temp&0x01;      //每次传输低字节
     temp>>=1;    //右移一位
     SCK=1;
   }
 


void Write_Ds1302( unsigned char address,unsigned char dat )    
{
  RST=0;
 _nop_();
  SCK=0;
 _nop_();
  RST=1; 
    _nop_();   //启动
  Write_Ds1302_Byte(address); //发送地址
  Write_Ds1302_Byte(dat);  //发送数据
  RST=0;    //恢复
}

unsigned char Read_Ds1302 ( unsigned char address )
{
  unsigned char i,temp=0x00;
  RST=0;
 _nop_();
  SCK=0;
 _nop_();
  RST=1;
 _nop_();
  Write_Ds1302_Byte(address);
  for (i=0;i<8;i++)   //循环8次 读取数据
   
   if(SDA)
   temp|=0x80;   //每次传输低字节
  SCK=0;
  temp>>=1;   //右移一位
   SCK=1;
 }
  RST=0;
 _nop_();  //以下为DS1302复位的稳定时间
  RST=0;
 SCK=0;
 _nop_();
 SCK=1;
 _nop_();
 SDA=0;
 _nop_();
 SDA=1;
 _nop_();
 return (temp);   //返回
}

void Read_RTC(void)  //读取日历
{
 unsigned char i,*p;
 p=read_rtc_address;  //地址传递
 for(i=0;i<7;i++)  //分7次读取秒分时日月周年
 {
  l_tmpdate[i]=Read_Ds1302(*p);
  p++;
 }
}

void Set_RTC(void)  //设定 日历
{
 unsigned char i,*p,tmp;
 for(i=0;i<7;i++){           //BCD处理
  tmp=l_tmpdate[i]/10;
  l_tmpdate[i]=l_tmpdate[i]%10;
  l_tmpdate[i]=l_tmpdate[i]+tmp*16;
 }
  Write_Ds1302(0x8E,0X00);
 
  p=write_rtc_address; //传地址 
  for(i=0;i<7;i++)  //7次写入秒分时日月周年
  {
    Write_Ds1302(*p,l_tmpdate[i]);
    p++; 
  }
  Write_Ds1302(0x8E,0x80);
}

void tim(void) interrupt 1 using 1//中断,用于数码管扫描
{

    static unsigned char i,num;
    TH0=0xf5;
    TL0=0xe0;

  P0=table[l_tmpdisplay[i]];  //查表法得到要显示数字的数码段
 P2=table1[i];
 i++;
 if(i==8)
   {
    i=0;
    num++;
    if(10==num)       //隔段时间读取1302的数据。时间间隔可以调整
      {
   ReadRTC_Flag=1; //使用标志位判断
   num=0;
   }
   
    }
 }

5.4*4矩阵键盘

//行列扫描程序,可以自己定义端口和扫描方式,这里做简单介绍
#include //包含头文件
#define uchar unsigned char
#define uint  unsigned int

 

unsigned char const dofly[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
                      0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F
 
uchar keyscan(void);
void delay(uint i);

void main()
{
 uchar key;
 P2=0x00;//1数码管亮 按相应的按键,会显示按键上的字符
 while(1)
{
 key=keyscan();//调用键盘扫描,
 switch(key)
 {
  case 0x7e:P0=dofly[0];break;//0 按下相应的键显示相对应的码值
  case 0x7d:P0=dofly[1];break;//1
  case 0x7b:P0=dofly[2];break;//2
  case 0x77:P0=dofly[3];break;//3
  case 0xbe:P0=dofly[4];break;//4
  case 0xbd:P0=dofly[5];break;//5
  case 0xbb:P0=dofly[6];break;//6
  case 0xb7:P0=dofly[7];break;//7
  case 0xde:P0=dofly[8];break;//8
  case 0xdd:P0=dofly[9];break;//9
  case 0xdb:P0=dofly[10];break;//a
  case 0xd7:P0=dofly[11];break;//b
  case 0xee:P0=dofly[12];break;//c
  case 0xed:P0=dofly[13];break;//d
  case 0xeb:P0=dofly[14];break;//e
  case 0xe7:P0=dofly[15];break;//f
 }
 }
}
uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法
{
 uchar cord_h,cord_l;//行列值
 P3=0x0f;            //行线输出全为0
 cord_h=P3&0x0f;     //读入列线值
 if(cord_h!=0x0f)    //先检测有无按键按下
 {
  delay(100);        //去抖
  if(cord_h!=0x0f)
  {
    cord_h=P3&0x0f;  //读入列线值
    P3=cord_h|0xf0;  //输出当前列线值
    cord_l=P3&0xf0;  //读入行线值
    return(cord_h+cord_l);//键盘最后组合码值
   }
  }return(0xff);     //返回该值
}

void delay(uint i)//延时函数
{
while(i--);
}

6.红外解码LCD显示


//该程序使用LCD1602显示
#include
#include
#include

////////////////////////////////////////////////
#define TURE 1
#define FALSE 0

////////////////////////////////////////////////

sbit IR=P3^2;//红外接口标志
sbit RS = P2^4;//Pin4
sbit RW = P2^5; //Pin5
sbit E  = P2^6;//Pin6

#define Data  P0    //数据端口

unsigned int hour,minute,second,count;
char code Tab[16]="0123456789ABCDEF";

char data TimeNum[]="                ";
char data Test1[]="                  ";

////////////////////////////////////////////

unsigned char  irtime;//红外用全局变量

bit irpro_ok,irok;
unsigned char IRcord[4];
unsigned char   irdata[33];
void ShowString (unsigned char line,char *ptr);

//////////////////////////////////////////////

void Delay(unsigned char mS);
void Ir_work(void);
void Ircordpro(void);


////////////////////////////////////////////////////////////////
void Delay(unsigned char mS)//delay mS
{
 unsigned char us,usn;

 while(mS!=0)
  {
   usn = 4;
   while(usn!=0)
    {
     us=0xf0;
     while (us!=0) {us--;};
     usn--;
    }

   mS--;

  }
}


//////////////////////////////////////////////////////////////////
/

 

  void Ir_work(void)//红外键值散转程序
  {
      
       TimeNum[5] = Tab[IRcord[0]/16];
    TimeNum[6] = Tab[IRcord[0]%16];
    TimeNum[8] = Tab[IRcord[1]/16];
    TimeNum[9] = Tab[IRcord[1]%16];
    TimeNum[11] = Tab[IRcord[2]/16];
    TimeNum[12] = Tab[IRcord[2]%16];
    TimeNum[14] = Tab[IRcord[3]/16];
    TimeNum[15] = Tab[IRcord[3]%16];
 
       ShowString(1,TimeNum);

    irpro_ok=0;

  }


void Ircordpro(void)//红外码值处理函数
{
  unsigned char i, j, k;
  unsigned char 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
      {
             value=value|0x80;
   }
          else
      {
             value=value;
   }
          if(j<8)
      {
    value=value>>1;
   }
           k++;
         }
     IRcord[i]=value;
     value=0;    
     } irpro_ok=1;//处理完毕标志位置1
   
}

 


void DelayUs(unsigned char us)//delay us
{
 unsigned char uscnt;
 uscnt=us>>1;
 while(--uscnt);
}

void DelayMs(unsigned char ms)//delay Ms
{
 while(--ms)
   {
     DelayUs(250);
     DelayUs(250);
  DelayUs(250);
  DelayUs(250);
   }
}
void WriteCommand(unsigned char c)
{
 DelayMs(5);//short delay before operation
 E=0;
 RS=0;
 RW=0;
 _nop_();
 E=1;
 Data=c;
 E=0;
}

void WriteData(unsigned char c)
{
 DelayMs(5);   //short delay before operation
 E=0;
 RS=1;
 RW=0;
 _nop_();
 E=1;
 Data=c;
 E=0;
 RS=0;
}

void ShowChar(unsigned char pos,unsigned char c)
{
 unsigned char p;
 if (pos>=0x10)
    p=pos+0xb0; //是第二行则命令代码高4位为0xc
 else
    p=pos+0x80; //是第二行则命令代码高4位为0x8
 WriteCommand (p);//write command
 WriteData (c);   //write data
}

void ShowString (unsigned char line,char *ptr)
{
 unsigned char l,i;
 l=line<<4;
 for (i=0;i<16;i++)
 ShowChar (l++,*(ptr+i));//循环显示16个字符
}

void InitLcd()
{
 DelayMs(15);
 WriteCommand(0x38); //display mode
 WriteCommand(0x38); //display mode
 WriteCommand(0x38); //display mode
 WriteCommand(0x06); //显示光标移动位置
 WriteCommand(0x0c); //显示开及光标设置
 WriteCommand(0x01); //显示清屏

}


/////////////////////////////////////////////////////////////////

void main(void)
{
 EX0init(); // Enable Global Interrupt Flag
 TIM0init();

 InitLcd();//
 DelayMs(15);

 sprintf(Test1," www.haotun.com ");//the first line
 ShowString(0,Test1);

 sprintf(TimeNum,"Code            ");//the second line
 ShowString(1,TimeNum);


 while(1)//主循环
   {
    if(irok)
   
    Ircordpro();
     irok=0;
   }

    if(irpro_ok)//step press key
   {
    Ir_work();
     }
   }
}

7.蜂鸣器

  

#include

sbit SPK=P1^2;//定义蜂鸣器端口


void delay(unsigned int cnt)//延时
{
 while(--cnt);
}

main()
{
unsigned int i;
 while(1)
      {
    for(i=0;i<200;i++)//喇叭发声的时间循环,改变大小可以改变发声时间长短
          {
          delay(80);//参数决定发声的频率,估算值
          SPK=!SPK;
          }
       SPK=1;        //喇叭停止工作,间歇的时间,可更改
       delay(20000);
         


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
示波器使用时要注意的19个问题