文档库 最新最全的文档下载
当前位置:文档库 › 单片机 c语言例题

单片机 c语言例题

单片机 c语言例题
单片机 c语言例题

?1.设有一组数据{72,27,18,29,26,63,112,98,12,6},被定义在内部数据存储器中,用C51编程,将其拷贝到外部数据存储器中,并分别找出最大数与最小数存入外部数据存储器的max和min单元。

?#include

?#include

?#define max XBYTE [0x1000]

?#define min XBYTE [0x1001]

?unsigned char tab[]={72,27,18,29,26,63,112,98,12,6};

?void main()

?{unsigned int i,add=0x40;

?for(i=0;i<10;i++)

?{XBYTE[add+i]=tab[i];

?}

?max=XBYTE[add];

?min=XBYTE[add];

?for(i=0;i<10;i++)

?{if(XBYTE[add+i]>max)

?{max=XBYTE[add+i];}

?if(XBYTE[add+i]

?{min=XBYTE[add+i];}

?}

?while(1);

?}

? 2. 设有一组数据{0x21,0x34,0x91,0x01,0x65,0x87,0x98,0x31,0x63,0x90},被定义在内部数据存储器中,用C51编程,将其拷贝到外部数据存储器中,并求其累加和从P1口输出。

?#include

?#include

?unsigned char tab[]={0x21,0x34,0x91,0x01,0x65,0x87,0x98,0x31,0x63,0x90};

?void main()

?{unsigned int i,add0=0x40;

?unsigned char addx=0;

?for(i=0;i<10;i++)

?{XBYTE[add0+i]=tab[i];

?addx+= tab[i];

?}

?P1=addx;

?while(1) ;

?

?}

3.设有一组数据{0x6a,0x12,0x4d,0x51,0xc9},被定义在内部数据存储器中,用C51编程,分别将其转换成ASCII并存储到外部数据存储器0050H开始的单元中。

?#include

?#include

?#define dy 0x50

?unsigned char a[]={0x6a,0x12,0x4d,0x51,0xc9};

?void main()

?{unsigned char i,j;

?for(j=0;j<5;j++)

?{

?i=a[j]/16;

?if(i<10)

?{XBYTE[dy+2*j]=0x30+i;}

?else {XBYTE[dy+2*j]=0x37+i;}

?i=a[j]%16;

?if(i<10)

?{XBYTE[dy+2*j+1]=0x30+i;}

?else {XBYTE[dy+2*j+1]=0x37+i;}

?}

?while(1);

?}

4.设有一组数据{12,34,76,54,23,87,14,62,19,6},被定义在内部数据存储器中,用C51编程,先将其拷贝到内部数据存储器30H开始单元中,然后将其从小到大排序。

?#include

?#include

?unsigned char tab[]={12,34,76,54,23,87,14,62,19,6};

?void main()

?{unsigned int i,j,a;

?unsigned char *add0 ;

?add0=0x30;

?for(i=0;i<10;i++)

?{*(add0+i)=tab[i];}

?for(i=0;i<10;i++)

?{for(j=i+1;j<10;j++)

?{if(*(add0+i)>*(add0+j))

?{a=*(add0+j);

?*(add0+j)=*(add0+i);

?*(add0+i)=a;}

?}

?}

?while(1) ;

?

?}

5:外部中断0引脚(P3.2)接一个开关,P1.0接一个发光二极管。开关闭合一次,发光二极管改变一次状态。

本例解决外部中断如何应用。

#include “reg51.h”

#include “intrins.h”

sbit p10=P1^0;

void delay(void)

{

int a=5000;

while(a--)_nop_();

}

void int_srv(void)interrupt 0 using 1

{

delay();

if(INT0==0)

{P10= ~P10;while(INT0==0);}

}

void main()

{ P10=0;

IT0=1

EA=1;

EX0=1;while(1);

}

6:从P1.0输出方波信号,周期为50ms。设单片机的focs=6MHz。

本例解决定时器及其中断的应用。

#include “reg51.h”

void main()

{

TMOD=0x01;

TH0=(65536-12500)/256;

TL0=(65536-12500)%256;

ET0=1;

EA=1;

TR0=1;

while(1);

}

void T0_srv(void)interrupt 1 using 1

{

TH0=(65536-12500)/256;

TL0=(65536-12500)%256;

P10=~P10;

}

7.设晶振频率为6MHZ,要求在单片机的P2.7口上输出周期为1秒的连续方波信号,用定时器中断方式定时,请用C语言编程实现该功能。

?#include

?sbit D1=P2^7;

?unsigned char Countor;

?void main(void)

?{

?EA=1;

?ET0=1;

?TMOD=0X01;

?TH0=(65536-25000)/256; //定时50ms

?TL0=(65536-25000)%256;

?TR0=1;

?while(1);

?}

?void Time0(void) interrupt 1 using 0

?{

?Countor++;

?if(Countor==10)

?{ D1=~D1;

?Countor=0;

?}

?TH0=(65536-25000)/256;

?TL0=(65536-25000)%256;

?}

8:如图所示,单片机扩展可编程接口芯片8155,8155PA口控制8只发光二极管,形成走马灯,每位点亮的时间为0.5秒。单片机晶振为6 MHZ

8155的端口地址如下:

命令口地址(COM8155): FEF8H

PA口地址(PA8155):FEF9H

PB口地址(PB8155):FEFAH

PC口地址(PC8155):FEFBH

#include “reg51.h”

#include “absacc.h”

#define COM8155 XBYTE[0xfef8]

#define PA8155 XBYTE[0xfef9]

void delay(void)/*延时1ms*/

{

TMOD=0X01

TH0=(65536-500)/256;

TL0=(65536-500)%256;

TR0=1;

while(~TF0);

TF0=0;

TR0=0;

}

main()

{

unsigned int i;

char disp_word=0x01;/*从第1位开始点亮*/

COM8155=0x01;/*初始化8155*/

do {

PA8155= disp_word;/*输出去点亮一位*/

for(i=0;i<500;i++)/*点亮0.5秒*/

{delay();}

disp_word= disp_word<<1;/*左移控制字,准备点亮下一位*/

if(disp_word==0)disp_word=0x01;

} whlie(1);

}

9:独立键盘,用C语言实现。

?如图所示,P1.0~P1.3分别接开关S1~S4。S1按下时使外部20H单元内容加1;S2按下时使外部20H单元内容减1;S3按下时使外部20H单元内容清零;S4按下时使外部20H单元内容全1。用C51编程实现该功能,要求有10ms去抖动功能。系统晶振12MHZ

#include “reg51.h”

#include “absacc.h”

void delay(void)/*延时1ms*/

{

TMOD=0X01

TH0=(65536-1000)/256;

TL0=(65536-1000)%256;

TR0=1;

while(!TF0);

TF0=0;

TR0=0;

}

main()

{

char x,i;

P1=0xff;

loop:x=P1;

x=x&0x0f;

if(x==0f)goto loop;

for(i=0;i<10;i++)/*延时10ms去抖动*/ {delay();}

x=P1;

x=x&0x0f;

if(x==0f)goto loop;

switch(x)

{

case 0x0E:PBYTE[0x20]= PBYTE[0x20]+1;break;/*20单元加1*/

case 0x0D:PBYTE[0x20]= PBYTE[0x20]-1;break;/*20单元减1*/

case 0x0B:PBYTE[0x20]= 0x00;break;/*20单元清0*/

case 0x07:PBYTE[0x20]= 0xff;/*20单元置全1*/

}

goto loop;

}

?10.设晶振频率为6MHZ,一个共阳数码管的各段接P2口,公共端接VCC。希望在数码管上显示0~9计数,一秒钟数字加1,一秒时间用定时器0定时实现,请用C 语言编程实现该功能。共阳数码管0~9的段码表为:0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90。

?unsigned char code Tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90} ;

?void main()

?{ unsigned char i=0;

?unsigned char Countor;

?TMOD=0x01;

?TH0=(65536-25000)/256;

?TL0=(65536-25000)%256; //定时50ms,1s=20*50ms

?TR0=1;

?Countor=0;

?while(1)

?{ Countor++;

?while(TF0==0);

?TF0=0;

?if(Countor==20)

?{ P2=Tab[i];

?i++;

?if(i>9) i=0;

?Countor=0;

?}

?}

11.动态共阴显示,用C语言实现。单片机晶振为6MHZ

#include “reg51.h”

#include “intrins.h”

char code dispdata[ ]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};char dis_dat[4];

void delay(void)/*延时1ms*/

{

TH0=(65536-500)/256;

TL0=(65536-500)%256;

TR0=1;

while(!TF0);

TF0=0;

TR0=0;

}

void disp(char ch1)/*显示函数*/

{ static char ch=0x01;

P1=ch;/*送位码

P2=dispdata[dis_dat[ch1]];

ch=ch<<1;

if(ch==0x10)ch=0x01;

}

main()

{ char ch1;

TMOD=0x01;

while(1)

{

for(ch1=0;ch1<4;ch1++)/*对四位LED扫描一遍*/

{disp(ch1);

delay();

}

delay();

delay();

}

}

?12.设晶振频率为12MHZ,用定时器T1中断控制两个LED以不同周期闪烁,用C 语言编程实现该功能。

?#include

?sbit D1=P2^0; //将D1位定义为P2.0引脚

?sbit D2=P2^1; //将D2位定义为P2.1引脚

?unsigned char Countor1; //设置全局变量,存储定时器T1中断次数

?unsigned char Countor2; //设置全局变量,存储定时器T1中断次数

?void main(void)

?{

?EA=1;

?ET1=1

?TMOD=0x10;

?TH1=(65536-50000)/256; //定时50ms

?TL1=(65536-50000)%256;

?TR1=1;

?Countor1=0; //从0开始累计中断次数

?Countor2=0; //从0开始累计中断次数

?while(1);

?}

?void Time1(void) interrupt 3 using 0 //

?{

?Countor1++; //Countor1自加1

?Countor2++; //Countor2自加1

?if(Countor1==2) //若累计满2次,即计时满100ms

?{

?D1=~D1; //按位取反操作,将P2.0引脚输出电平取反

?. Countor1=0;

?}

?if(Countor2==8) //若累计满8次,即计时满400ms

?{

D2=~D2; //按位取反操作,将P2.1引脚输出电平取反

Countor2=0;

?}

?TH1=(65536-50000)/256;

?TL1=(65536-50000)%256;

?}

?13.设LED指示灯为低电平点亮,P1口输出控制8只LED跑马灯,用C语言编程实现。

?#include

?void delay(void)

?{

?unsigned char i,j;

?for(i=0;i<250;i++)

?for(j=0;j<250;j++)

?;

?}

?void main(void)

?{

?while(1)

?{ p1=0xfe;

?delay();

?p1=0xfd;

?delay();

?p1=0xfb;

?delay();

?p1=0xf7;

?delay();

?p1=0xef;

?delay();

?p1=0xdf;

?delay();

?p1=0xbf;

?delay();

?p1=0x7f;

?delay(); }

14.如图所示,对8个通道轮流采集一次,采集的结果放在数组ad中。

#include “reg51.h”

#include “absacc.h”

sbit ad_busy=P3^2;

main()

{ static char idata ad[8];

char i;

char pdata *ad_chl;

ad_chl=0x78;/*设置初始通道地址*/

for(i=0;i<8;i++)

{

*ad_chl=0;/*启动A/D转换*/

i=i;/*等待EOC信号变低*/

i=i;

while(ad_busy==1); /*查询*/

ad[i]=*ad_chl;/*存放结果*/

ad_chl++ ;

}

while(1);

}

15:如图所示,要求DAC0832输出锯齿波电压信号,信号周期自由,用C语言写出相应程序。

#include “reg51.h”

#include “absacc.h”

#define DA0832 PBYTE[0x7f]

void delay(void)

{

unsigned char i,j;

for(i=0;i<250;i++)

for(j=0;j<250;j++)

}

main()

{

char i;

do {

for(i=0;i<255;i++)

{DAC0832=i;delay(); }

} while(1);

}

16:编写一个计数器程序,将T0作为计数器来使用,对外部信号计数,将计数字显示在数码管上。

?#include "reg51.h"

?#define uchar unsigned char

?#define uint unsigned int

?uchar code BitTab[]={0x7F,0xBF,0xDF,0xEF,0xF7,0xFB};//位驱动码

?uchar code DispTab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0

xA1,0x86,0x8E,0xFF};//字形码

?uchar DispBuf[6]; //显示缓冲区

?void Timer1() interrupt 3

?{ uchar tmp;

?Static uchar Count; //计数器,显示程序通过它得知现正显示哪个数码管

?TH1=(65536-3000)/256;

?TL1=(65536-3000)%256; //重置初值

?tmp=BitTab[Count]; //取位值

?P2=P2|0xfc; //P2与11111100B相或

?P2=P2&tmp; //P2与取出的位值相与

?tmp=DispBuf[Count];//取出待显示的数

?tmp=DispTab[tmp]; //取字形码

?P0=tmp;

?Count++;

?if(Count==6)

?Count=0;

?}

?void main()

?{ uint tmp;

?P1=0xff;

?P0=0xff;

?TMOD=0x15; //定时器0工作于计数方式1,定时器1工作于定时方式1 ?TH1=(65536-3000)/256;

?TL1=(65536-3000)%256; //定时时间为3000个周期

?TR0=1; //计数器0开始运行

?TR1=1;

?EA=1;

?ET1=1;

?for(;;)

?{ tmp=TL0|(TH0<<8);//tmp=TH0*256+TL0取T0中的数值

?DispBuf[5]=tmp%10;

?tmp/=10;

?DispBuf[4]=tmp%10;

?tmp/=10;

?DispBuf[3]=tmp%10;

?tmp/=10;

?DispBuf[2]=tmp%10;

?DispBuf[1]=tmp/10;

?DispBuf[0]=0;

?}}

17:矩阵键盘扫描。p3.7~p3.4是行线,用于输出。P3.3~P3.0是列线,用于输入。

?#include "at89x52.h"

?typedef unsigned char uchar;

?typedef unsigned int uint;

?void mDelay(uint j)

?{ uint i;

?for(;j>0;j--)

?for(i=0;i<125;i++);

?}

?uchar GetKey()

?{ uchar KeyValue,tmp;

?uchar i;

?P3=0x0f; //用于输入的P3口的I/O线置高,用于输出的I/O口线全部为低

?KeyValue=P3; //获得P3口的值

?KeyValue|=0xf0; //低4位置高

?if(KeyValue==0xff)

?return 0; //无键按下

?else

?mDelay(10); //否则延时10ms去键抖动

?P3=0x0f; //用于输入的P3口的I/O线置高,用于输出的I/O口线全部为低

?KeyValue=P3; //获得P3口的值

?KeyValue|=0xf0; //低4位置高

?if(KeyValue==0xff)

?return 0; else

?{ for(i=0;i<4;i++)

?{ P3=0xff; //P3口全部置高

?P3&=~(0x80>>i);

?/*0x80就是10000000B,当i=0时,0x80>>i即为该数本身,~为取反,即P3和01111111B相与

?如果i=1,那么0x80>>i的结果是01000000,取反后是10111111,即P3和该数相与

?KeyValue=P3; //取键值

?KeyValue|=0xf0;

?if(KeyValue!=0xff)

?break;

?}

?KeyValue&=~(0x10<

?for(;;) //以下等待键释放

?{ P3=0x0f;

?tmp=P3;

?tmp|=0xf0;

?if(tmp==0xff)

?break; }

?return KeyValue;

?}

?}

?void main()

?{

?uchar KeyValue;

?for(;;)

?KeyValue=GetKey();

?}

?以下是按下各键后返回的键值:?

?E7,EB,ED,EE

?D7,DB,DD,DE

?B7,BB,BD,BE

?77,7B,7D,7E

相关文档