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

发布者:科技律动最新更新时间:2016-02-25 来源: eefocus关键字:单片机  C语言  程序举例 手机看文章 扫描二维码
随时随地手机看文章
本着共同学习,共同进步的目的,把我搞到的资料不辞辛苦的发上来,供初学者参考,希望可以对大家有帮助!所有程序是本人买 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);
         
   }
}

关键字:单片机  C语言  程序举例 引用地址:单片机C语言程序举例(一)

上一篇:单片机C语言程序举例(三)
下一篇:单片机C语言程序举例(二)

推荐阅读最新更新时间:2024-03-16 14:45

基于ARM的32位MCU提供SoC设计参考
随着制造工艺的迅猛发展,MCU在外设集成、性能、功耗及降低成本方面都有了长足的进展,几乎能提供与SoC相类似的性能,而且应用数量正日趋增长。特别是基于ARM的32位MCU,为SoC设计人员提供了快速低廉的设计参考。 系统级芯片(SoC)技术可以看作是专用集成电路(ASIC)的一种新的设计模式,较之ASIC,其设计周期短,能为设计人员消除设计特殊应用时遇到的障碍。SoC的性能接近于成熟的ASIC,不过它仍需要掩膜,并不能节省ASIC所需的大部分设计成本。 随着先进的制造工艺将更多外设集成于芯片、降低功耗和提供更多的性能,ASIC和标准32位微控制器(MCU)的区别也在缩小。对于基于ARM内核的微控制器而言,当集成了关键外设时,这
[单片机]
μCOS-Ⅱ在ARM系列单片机S3C44B0x上的移植
引 言 目前,嵌入式系统在工业控制、家用电器、移动通信、PDA等各种领域得到了越来越广泛的应用。由于用户对嵌入式产品的性能要求越来越高,程序设计也变得越来越复杂,这就需要一个通用的嵌入式实时操作系统来对其进行管理和控制。对移植了操作系统的嵌入式系统进行设计和开发,可以大大减小程序员的负担,对于不同的应用可以按照相同的步骤来完成系统的设计。 μC/OS-Ⅱ是一种简单高效、源代码公开的嵌入式实时操作系统,具有良好的可扩展性和可移植性,被广泛的应用到各种嵌人式处理器上。μCOS-Ⅱ操作系统拥有可固化,可裁剪,可剥夺性的实时内核,可同时管理64个系统任务。利用移植μCOS-Ⅱ操作系统的嵌入式微处理器来设计和开发产品,对于提高产品
[单片机]
μCOS-Ⅱ在ARM系列<font color='red'>单片机</font>S3C44B0x上的移植
STM32F103单片机生成16路PWM波
单片机输出pwm波在项目中是恨常用的一个功能,今天就总结一下用STM32F103C8T6单片机输出16路 pwm波。 使用keil5软件,用标准库函数来实现。 首先看定时器初始化 void TIM1_PWM_Init(u16 arr, u16 psc) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; TIM_OCInitTypeDef TIM_OCInitSturcture; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | R
[单片机]
STM32F103<font color='red'>单片机</font>生成16路PWM波
高性价比MCU的传奇 —— STM32H7系列
STM32可以列出很多关键词,跨界通用、全面覆盖、完整生态、超低功耗、多种应用。而高性价比是最受用户关注的关键词。 从2007年推出世界第一款Cortex-M MCU,到2020年新推出的H7系列高性能大内存产品,十几年来,ST在MCU市场上不断加大创新力度,STM32持续出新。5大家族、17条产品线、千款型号、I/O兼容,STM32大家族跨越通用、超低功耗、高性能和超高性价比MCU,全面覆盖各种应用需求,打造出了32位MCU的大帝国。 谈到STM32的高性能家族产品,大家已经对STM32F2/F4/F7耳熟能详。之后的STM32H7系列继承和发展了高性能产品家族的特性,其中单核的H743/750和双核745/747也已经得到了
[单片机]
基于51单片机的OLED显示图片文字
一、前言 从性能来说OLED屏幕分辨率相对较高,引脚也少很多,占用的I/O口会少很多。从功耗来说首先oled显示屏不需要背光灯,当有电流通过时,这些有机材料就可以发光,而且3.3V~5V之间都可以使用。从外观来说体型更小,重量更轻更薄,可用来制作许多小型显示设备。这次我使用的是四个引脚的0.95寸oled显示屏,进行文字图片的循环显示。 二、OLED模块介绍 1、液晶显示屏 液晶显示器,为平面超薄的显示设备,它由一定数量的彩色或黑白像素组成,放置于光源或者反射面前方。液晶显示器功耗很低,因此倍受工程师青睐,适用于使用电池的电子设备。它的主要原理是以电流刺激液晶分子产生点、线、面配合背部灯管构成画面。 液晶显示器的工作原理:液晶
[单片机]
基于51<font color='red'>单片机</font>的OLED显示图片文字
MCS51单片机的定时器/计数器概念 非常好的寄存器关系图
一、MCS-51单片机的定时器/计数器概念 单片机中的定时器和计数器其实是同一个物理的电子元件,只不过计数器记录的是单片机外部发生的事情(接受的是外部脉冲),而定时器则是由单片机自身提供的一个非常稳定的计数器,这个稳定的计数器就是单片机上连接的晶振部件;MCS-51单片机的晶振经过12分频之后提供给单片机的只有1MHZ的稳定脉冲;晶振的频率是非常准确的,所以单片机的计数脉冲之间的时间间隔也是非常准确的,这个准确的时间间隔是1微秒; MCS-51单片机外接的是12MHZ的晶振(实际上是11.0592MHZ),所以,MCS-51单片机内部的工作频率(时钟脉冲频率)是12MHZ/12=1MHZ=1000000次/秒=1000000条指令
[单片机]
MCS51<font color='red'>单片机</font>的定时器/计数器概念 非常好的寄存器关系图
利用单片机构成高精度PWM式12位D/A
.前言 在用单片机制作的变送器类和控制器类的仪表中,需要输出1—5V或4—20mA的直流信号的时候,通常采用专用的D/A芯片,一般是每路一片。当输出信号的精度较高时,D/A芯片的位数也将随之增加。在工业仪表中,通常增加到12位。12位D/A的价格目前比单片机的价格要高得多,占用的接口线数量也多。尤其是在需隔离的场合时,所需的光电耦合器数量与接口线相当,造成元器件数量大批增加,使体积和造价随之升高。如果在单片机控制的仪表里用PWM方式完成D/A输出,将会使成本降低到12位D/A芯片的十分之一左右。我们在S系列流量仪表中采用了这种方式,使用效果非常理想。下面介绍一下PWM方式D/A的构成原理。 .电路原理 一般1
[单片机]
利用<font color='red'>单片机</font>构成高精度PWM式12位D/A
以C8051F020单片机为控制核心的人机交互系统设计
在现代各类仪器的开发中,人机交互功能正起着无可替代的作用。人机交互界面友好的仪器将更容易操作和使用,从而提高工作效率。液晶显示器(LCD)具有功耗低、价格低、寿命长、接口控制方便等特点,在科研与设计领域正发挥着越来越大的作用。FPGA 作为单片机外设的接口芯片,可以大大简化接口电路,通过对FPGA 进行编程,可以实现常用的译码、地址选通等功能。 本文以C8051F020 单片机与FPGA 互连系统为控制核心,以液晶显示控制器T6963C 为例,结合行扫描键盘,简述了一种人机交互功能的设计。 1 系统设计方案: FPGA 可在很大程度上扩展单片机的资源,然而人机交互功能仍应尽量减少对单片机及FPGA 的资源消耗, 以便将更多
[单片机]
以C8051F020<font color='red'>单片机</font>为控制核心的人机交互系统设计
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved