单片机 c语言例题

更新时间:2023-12-21 08:07:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

? 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]

? } ? 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]; 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)%6; ET0=1; EA=1; TR0=1; while(1); }

void T0_srv(void)interrupt 1 using 1 { TH0=(65536-12500)/256; TL0=(65536-12500)%6; 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)%6; ? 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)%6; ? }

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)%6; 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)%6; 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)%6; //定时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)%6; 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)%6; ? 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)%6; }

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 \

? #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,0xA1,0x86,0x8E,0xFF}; //字形码 ? uchar DispBuf[6]; //显示缓冲区 ? void Timer1() interrupt 3 ? { uchar tmp;

? Static uchar Count; //计数器,显示程序通过它得知现正显示哪个数码管 ? TH1=(65536-3000)/256;

? TL1=(65536-3000)%6; //重置初值 ? 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)%6; //定时时间为3000个周期 ? TR0=1; //计数器0开始运行 ? TR1=1; ? EA=1; ? ET1=1; ? for(;;)

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

? DispBuf[4]=tmp; ? tmp/=10;

? DispBuf[3]=tmp; ? tmp/=10;

? DispBuf[2]=tmp; ? DispBuf[1]=tmp/10; ? DispBuf[0]=0; ? }}

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

? #include \

? 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

本文来源:https://www.bwwdw.com/article/n5a5.html

Top