单片机c语言散转,单片机C语言程序举例(一)

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

1.流水灯C程序本文引用地址:http://www.eepw.com.cn/article/201611/320072.htm

#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);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值