蓝桥杯单片机编程笔记Word文件下载.docx

上传人:b****5 文档编号:17429722 上传时间:2022-12-01 格式:DOCX 页数:41 大小:931.17KB
下载 相关 举报
蓝桥杯单片机编程笔记Word文件下载.docx_第1页
第1页 / 共41页
蓝桥杯单片机编程笔记Word文件下载.docx_第2页
第2页 / 共41页
蓝桥杯单片机编程笔记Word文件下载.docx_第3页
第3页 / 共41页
蓝桥杯单片机编程笔记Word文件下载.docx_第4页
第4页 / 共41页
蓝桥杯单片机编程笔记Word文件下载.docx_第5页
第5页 / 共41页
点击查看更多>>
下载资源
资源描述

蓝桥杯单片机编程笔记Word文件下载.docx

《蓝桥杯单片机编程笔记Word文件下载.docx》由会员分享,可在线阅读,更多相关《蓝桥杯单片机编程笔记Word文件下载.docx(41页珍藏版)》请在冰豆网上搜索。

蓝桥杯单片机编程笔记Word文件下载.docx

ﻩP2=((P2&

0x1f)|0xc0);

P0=(1<<dspcom);

P2=P2&

0x1f;

//段码输入

P2=((P2&0x1f)|0xe0);

ﻩP0=tab[dspbuf[dspcom]];

ﻩif(++dspcom==8)

ﻩdspcom=0;

}

注意:

这里1左移dspcom位,刚开始dspcom=0,则1左移dspcom位依旧为1,接着dspcom每次自增1,1对应二进制00000001,即把1每次向左移,每次都比上一次多移一位,直至8位移完,对应8个数码管。

定时器配置:

这里只需记住定时器的配置,知道怎么使用就可以了。

首先有两个定时器,T0和T1,(也有的单片机有T2),定时器有4种工作方式0,1,2,3;

其中最常用的是方式1(16位),其次是方式2(8位自动重装,串口通讯中断会用到)。

定时器需要配置:

TMOD|=0x01;

配置成使用定时器0,工作方式为1;

同理使用定时器1工作方式1:

TMOD |=0x10;

则同时使用两个定时器且工作方式为1,那么可以:

TMOD|=0x11;

定时器1配置成工作方式2:

TMOD|=0x20;

接着配置(以定时器0举例):

TH0=(65535-2000)/256;

//配置初值

TL0=(65535-2000)%256;

ET0=1;

TR0=1;

//定时0中断

EA=1;

//总中断

定时器1也是同理的,只不过0要改成1.

接着定时中断函数和优先级:

定时器0

voidisr_timer_0(void) interrupt1//默认中断优先级1

 TH0=(65536-2000)/256;

 TL0 =(65536-2000)%256;

//定时器重载

display();

定时器1:

voidisr_timer_1(void)  interrupt 3 //默认中断优先级3

  TH0=(65536-2000)/256;

 TL0 =(65536-2000)%256;

 //定时器重载

 display();

定时器0优先级为1,定时器1为3,串口中断优先级为4,总共有5个中断源,后面还会介绍外部中断和串口中断。

数码管动态扫描,显示函数放在定时中断函数里面,2ms扫一次是最稳定的!

!

三、矩阵键盘

矩阵键盘需要死记了!

这里不再讲独立键盘。

第二种单片机键盘扫描代码(没有消抖):

sfrP4^4=0xC0;

//键盘定义

sbit r1=P3^0;

//4行

sbitr2=P3^1;

sbitr3=P3^2;

sbit r4=P3^3;

//4列

sbitc1=P4^4;

sbitc2=P4^2;

sbitc3=P3^5;

sbitc4=P3^4;

//读取矩阵键盘键值

unsignedcharkey_scan()

unsignedcharkey_value;

r1=0;

r2=r3=r4=1;

ﻩc1=c2=c3=c4=1;

if(!

c1)key_value=0;

elseif(!

c2)key_value=1;

elseif(!

c3)key_value=2;

c4)key_value=3;

 r2=0;

ﻩr1=r3=r4=1;

ﻩc1=c2=c3=c4=1;

ﻩif(!

c1)key_value=4;

else if(!

c2)key_value=5;

ﻩelseif(!

c3)key_value=6;

else if(!

c4) key_value=7;

r3=0;

r2=r1=r4=1;

ﻩc1=c2=c3=c4=1;

ﻩif(!

c1)key_value=8;

ﻩelseif(!

c2) key_value=9;

elseif(!

c3)key_value=10;

ﻩelseif(!

c4)key_value=11;

r4=0;

r2=r3=r1=1;

ﻩc1=c2=c3=c4=1;

if(!

c1)key_value=12;

ﻩelse if(!

c2)key_value=13;

elseif(!

c3)key_value=14;

else if(!

c4)key_value=15;

ﻩreturnkey_value;

四、串口通讯和串口中断

串口中断配置只需记住几个寄存器就行了,

初始化:

SCON =0x50;

//串口配置成模式1

TMOD|=0x20;

//定时器1,方式2,8位自动重装

TH1=256-(unsigbedchar)(SYSTEMCLOK/BAUDRATE/384+0.5);

//定时初值

ﻩES=1;

  ﻩ //串口中断打开

ﻩTR1=1;

   //启动定时器1

ﻩEA=1;

ﻩ//总中断打开

这里必须使用定时器1,不能用定时器0.

下面是模块化的函数:

void Uart_Init()

SCON= 0x50;

TMOD |=0x20;

ﻩTH1=256-(SYSREMCLOCK/BAUDRATE/384+0.5);

ﻩES=1;

TR1=1;

EA=1;

void UartSend(unsignedchar*pBuff,intlength)

unsignedcharc;

int i=0;

for(i=0;

i<

length;

i++)

ﻩc=pBuff[i];

SBUF=c;

while(TI==0);

TI=0;

接收数据可以这样写:

定义全局变量:

unsignedcharuart_buf[100];

//串口缓冲区

unsignedintuart_Count=0;

//串口数据长度

voiduart_inte()interrupt 4

ﻩunsignedcharc;

if(RI)

{

ﻩﻩRI=0;

ﻩﻩc=SBUF;

ﻩuart_buf[uart_Count]=c;

ﻩﻩuart_Count++;

}ﻩﻩ

如果可以指定的接收,可以这样写

//串口中断服务函数

void isr_uart(void)interrupt4{

if(RI){

 RI=0;

//清除接收标志位

  rxbuf[rxcnt] =SBUF;

  if(rxbuf[rxcnt] =='

\n'

){

     rxcnt=0;

   rx_over=1;

   ES =0;

//回车为接收结束标志,检测到回车符后,关闭串口中断

  }

ﻩﻩelse{

ﻩrxcnt++;

ﻩﻩ}

 }

当接收完一帧数据时关闭串口中断,设一个标志位,处理完之后再打开。

#include"

reg51.h"

#include"

intrins.h"

typedefunsigned char BYTE;

typedef unsignedint WORD;

BYTEcode_tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};

chararry[10]="

I CAN PLAY";

unsignedchar x;

#define FOSC11059200//12000000L   //系统频率

#defineBAUD115200   //串口波特率

#defineNONE_PARITY 0    //无校验

#defineODD_PARITY 1 //奇校验

#defineEVEN_PARITY2 //偶校验

#defineMARK_PARITY  3 //标记校验

#defineSPACE_PARITY  4  //空白校验

#define PARITYBITNONE_PARITY //定义校验位

sfr AUXR=0x8e;

       //辅助寄存器

sfr P_SW1=0xA2;

   //外设功能切换寄存器1

#defineS1_S0 0x40    //P_SW1.6

#defineS1_S10x80  //P_SW1.7

sbitP22=P2^2;

bitbusy;

voidSendData(BYTEdat);

voidSendString(char*s);

voidmain()

 ACC= P_SW1;

  ACC&

=~(S1_S0| S1_S1);

//S1_S0=0S1_S1=0

 P_SW1 =ACC;

    //(P3.0/RxD,P3.1/TxD)

  

//ACC= P_SW1;

// ACC&

=~(S1_S0|S1_S1);

 //S1_S0=1S1_S1=0

//ACC |=S1_S0;

  //(P3.6/RxD_2,P3.7/TxD_2)

//P_SW1 =ACC;

 

// 

//ACC=P_SW1;

// ACC &

=~(S1_S0|S1_S1);

 //S1_S0=0S1_S1=1

// ACC|=S1_S1;

      //(P1.6/RxD_3,P1.7/TxD_3)

// P_SW1 =ACC;

 

//#if (PARITYBIT==NONE_PARITY)

   SCON=0x50;

     //8位可变波特率

//#elif(PARITYBIT==ODD_PARITY)|| (PARITYBIT ==EVEN_PARITY)|| (PARITYBIT==MARK_PARITY)

// SCON =0xda;

    //9位可变波特率,校验位初始为1

//#elif(PARITYBIT==SPACE_PARITY)

//  SCON= 0xd2;

   //9位可变波特率,校验位初始为0

//#endif

AUXR= 0x40;

   //定时器1为1T模式

  TMOD = 0x20;

    //定时器1为模式2(8位自动重载)

TL1 = (256-(FOSC/32/BAUD));

//设置波特率重装值

 TH1 =(256-(FOSC/32/BAUD));

TR1=1;

  //定时器1开始工作

 ES= 1;

   //使能串口中断

  EA=1;

   while

(1)

ﻩ{

//SendString(arry);

SendString("

ICAN PLAY~~\r\n");

//上位机显示接收文本模式

//ﻩSendData(x);

}

/*----------------------------

UART中断服务程序

-----------------------------*/

voidUart() interrupt4using1

  if(RI)//单片机接收数据,发送数字0~9,可在数码管上显示,发送hex模式

  {

 RI=0;

   //清除RI位

// P0= SBUF;

ﻩx=SBUF;

//将缓存器的数据赋值给x

P0=0xff;

    //消隐

ﻩﻩP2|=0xe0;

ﻩP2&=0x1f;

ﻩﻩ

P0=code_tab[x];

ﻩ//段选

ﻩP2|=0xe0;

ﻩP2&=0x1f;

ﻩP0=0x01;

ﻩﻩ//位选第一位

ﻩﻩP2|=0xc0;

ﻩﻩP2&=0x3f;

 }

 if (TI)

 {

 TI=0;

     //清除TI位

  busy =0;

    //清忙标志

/*----------------------------

发送串口数据

----------------------------*/

void SendData(BYTE dat)

 while(busy);

   //等待前面的数据发送完成

 ACC=dat;

    //获取校验位P(PSW.0)

if(P)       //根据P来设置校验位

 {

#if(PARITYBIT== ODD_PARITY)

   TB8=0;

 //设置校验位为0

#elif(PARITYBIT==EVEN_PARITY)

  TB8= 1;

    //设置校验位为1

#endif

  }

   else

 {

#if(PARITYBIT==ODD_PARITY)

  TB8 = 1;

    //设置校验位为1

#elif (PARITYBIT ==EVEN_PARITY)

 TB8=0;

    //设置校验位为0

#endif

  busy=1;

 SBUF=ACC;

     //写数据到UART数据寄存器

/*----------------------------

发送字符串

----------------------------*/

voidSendString(char*s)

while(*s)    //检测字符串结束标志

  {

SendData(*s++);

     //发送当前字符

记不住可以看手册!

reg51.h"

#include "

typedefunsigned charBYTE;

typedefunsignedintWORD;

#defineFOSC11059200L

#define BAUD115200

sfr AUXR=0x8e;

 //辅助寄存器

sbitP22=P2^2;

bit busy;

voidSendData(BYTE dat);

voidSendString(char*s);

voidmain()

ﻩSCON=0x50;

ﻩAUXR=0x40;

ﻩ//设置定时器T1为1T,即一个机器周期模式

TMOD=0x20;

ﻩTL1=(256-(FOSC/32/BAUD));

TH1=(256-(FOSC/32/BAUD));

ﻩES=1;

EA=1;

SendString("

Hello"

);

ﻩwhile

(1);

voidUart()interrupt 4 using1

if(RI)

ﻩRI=0;

ﻩﻩP0=SBUF;

ﻩ}

if(TI)

TI=0;

ﻩbusy=0;

voidSendData(BYTEdat)

while(busy);

busy=1;

SBUF=dat;

voidSendString(char*s)

ﻩwhile(*s)

SendData(*s++);

五、外部中断的使用

#include<

reg52.h>

sbitL1=P0^0;

intmain(){

 IT0=1;

//IT0=1,下降沿触发外部中断0,IT0=0边沿触发

ﻩEX0=1;

//使用外部中断0

ﻩEA=1;

while

(1){

ﻩ}

void Ex_int0()interrupt0//外部中断优先级最高

P2=((P2&0x1f)|0x80);

ﻩL1=~L1;

P2=(P2&

0x1f);

}

其中,外部中断的引脚控制是P3^2,P3^3,即对应独立按键的S5,S4。

六、实时时钟DS1302的使用

蓝桥杯提供函数,解释为:

里面的命令和写入的数据可以看芯片手册:

左侧的READ、WRITE分别是读写的命令,BIT7-BIT0是要写入的数据,根据需要进行配置。

DS1302只需记住这两个函数即可:

Write_Ds1302(,)与Read_Ds1302(x),配置看手册。

重点:

芯片表说明:

第一行:

秒->

因为秒的范围是0-59,所以6,5,4位表示秒的十位,3,2,1,0表示个位,十位最大是5,所以三位即可。

第二行:

跟上面一样;

第三行:

7位:

1为12小时制,0为24小时制;

5位:

12小时制时为0表示上午,1表示下午,24小时制时,和4位一起表示小时的十位;

其余的时间一样的表示。

倒数第二行:

只看7位:

为1时禁止写数据,所以开始写数据时必须置0;

读数时:

需要加“写操作这一行代码”。

读的话直接按照命令读即可。

DS1302进阶(BCD码转换):

解决之前60秒不能进位的问题。

1)写入初始值时,要把10十进制数转换为BCD码,

例:

写入时间->

17:

58:

50

Ds1302_Single_Byte_Write(0x8e,0x00);

//写操作

ﻩDs1302_Single_Byte_Write(0x85, ((17/10)<<

4| (17%10)));

//写时

 Ds1302_Single_Byte_Write(0x83,((58/10)<

<4|(58%10)));

//写分

Ds1302_Single_Byte_Write(0x81, ((50/10)<

<

4|(50%10)));

//写秒

Ds1302_Single_Byte_Write(0x8e,0x80);

//写保护

即转换的公式是:

((Value/10)<<

4|(Value%10)),可以写一个settime()函数。

2) 读数:

读回来的数要进行转换成十进制数

((ReadValue&0x70)>>

4)*10+(ReadValue&

0x0F);

八进制转十进制->

ReadValue=Ds1302_Single_Byte_Read(0x85);

ﻩﻩhour=((ReadValue&

0x70)>

>

4)*10 +(ReadValue&

!

(这句一定不要省)ﻩDs1302_Single_Byte_Write(0x00, 0x00);

//写操作

ﻩReadValue=Ds1302_Single_Byte_Read(0x83);

ﻩﻩminute=((ReadValue&0x70)>>

4)*10+(ReadValue&

0x0F);

Ds1302_Single_Byte_Write(0x00,0x00);

ReadValue=Ds1302_Single_Byte_Read(0x81);

ﻩsec=((ReadValue&

0x70)>>4)*10 +(ReadValue&

ﻩDs1302_Single_Byte_Write(0x00,0x00);

显示:

ﻩdspbuf[0]=hour/10;

ﻩdspbuf[1]=hour%10;

dspbuf[2]=minute/10;

ﻩdspbuf[3]=minute%10;

ﻩdspbuf[4]=sec/10;

ﻩﻩdspbuf[5]=sec%10;

七、PCF8591与IIC总线的使用

(1)IIC总线的使用:

比赛提供了IIC的两个库文件,IIC.h;

IIC.c,其中需要注意的函数是:

其中,该函数是初始化的,当使用AD转换的时候需要在main函数开始时调用,该函数内部只需看这句代码即可:

i2c_sendbyte(0x03);

//ADC通道3,板上有4个模拟输入口,分别为0,1,2,3;

设置哪一个模拟输入口就是根据这句代码,0x03表示通道3,这是根据芯片手册配置的,如图:

8位前6位不用管,都为0,最后两位就是配置选择哪一个通道的。

第二个函数:

读取AD转换后的数值,这个函数直接调用就可以了,函数内部如何实现不用管,但是需要注意的是:

该函数扫描调用最好是100ms。

第三个函数,上面的都是AD转换,即模拟信号转数字信号,下面这个函数是DA转换

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 教学研究 > 教学计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1