题目要求
主函数
1、main
2、iic
总结
题目要求
大致为:独立按键s5按钮去循环切换实现显示读取rb2的值,上电显示两位小数的电压值,按下s5后显示小数电压值,然后按下s5显示相应的电阻值,然后按下回到两位小数的电压显示。当电压处于2-3v之外时小灯L1以0.1s2-3v时L1点亮,其余小灯熄灭。按键s4每次按下一次通过串口发送一次电压:格式为:"U:2.15V\r\n",波特率为9600。
主函数
1、main
#include <stc15f2k60s2.h> #include <stdio.h> #include "iic.h" #include "intrins.h" #define uchar unsigned char #define uint unsigned int sbit Buzzer = P0^6; sbit Relay = P0^4; /************* 本地常量声明 **************/ uchar code t_display[]={ ///标准字库 // 0 1 2 3 4 5 6 7 8 9 A B C D E F 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71, //black - H J K L N o P U t G Q r M y 0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e, 0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46}; //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1 uchar code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //位码 uchar table[]={16,16,16,16,16,16,16,16}; uchar ReadData,Trg,Cont; bit key_flag; //指示灯 uchar LED; bit led_flag; //adc数字量 uchar temp; uint V_num1; uchar V_num2;//电压 //模式 uchar set_mode; //串口 bit send_flag;//发送标志 char rx='1'; bit rxc=0; float v_num; void Delay300ms() //@12.000MHz { unsigned char i, j, k; _nop_(); _nop_(); i = 14; j = 174; k = 224; do { do { while (--k); } while (--j); } while (--i); } //关闭外设 void allinit() { P2=0Xa0;Buzzer=0;Relay=0;P2=0X00; P2=0X80;P0=0XFF;P2=0X00; } void Set_LED() { P2=0X80; P0=~LED; P2=0X00; } //串口 void UartInit(void) //9600bps@12.000MHz { SCON = 0x50; //8位数据,可变波特率 AUXR |= 0x40; ///定时器1时钟Fosc,即1T AUXR &= 0xFE; //串口1选择定时器1波特率发生器 TMOD &= 0x0F; ///设定时间16位自动重新安装 TL1 = 0xC7; ///设定时的初始值 TH1 = 0xFE; ///设定时的初始值 ET1 = 0; //禁止定时器1中断 TR1 = 1; ///启动定时器1 ES=1; EA=1; } void irs_uart() interrupt 4 { if(RI) { RI=0; rx=SBUF; ES=0; rxc=1; } } void uart_sendstring(unsigned char *str) { unsigned char *p; p=str; while(*p!='\0') { SBUF=*p; while(TI==0); TI=0; p ; } } //定时器0 void Timer0Init(void) //1毫秒@12.000MHz { EA=1;ET0=1; AUXR |= 0x80; //定时器时钟1T模式 TMOD &= 0xF0; //设置定时器模式 TL0 = 0x20; ///设定时初值 TH0 = 0xD1; ///设定时初值 TF0 = 0; //清除TF0标志 TR0 = 1; ///定时器0开始计时 } void Timer0() interrupt 1 { static uint smg_count,key_count,i,led_count; if( smg_count>=2) { smg_count=0; P2=0Xe0;P0=0XFF;P2=0X00; P2=0Xc0;P0=T_COM[i];P2=0X00; P2=0Xe0;P0=~t_display[table[i]];P2=0X00; i ; if(i>=8)i=0; } if( key_count>=10) { key_count=0; key_flag=1; } if( led_count>=100) { led_count=0; led_flag=~led_flag; } } void ReadKey() { ReadData=P3^0xff; Trg=ReadData&(ReadData^Cont); Cont=ReadData; } void disp_key() { if(key_flag) { key_flag=0; Set_LED(); ReadKey(); switch(Trg) { case 0x08://s4 send_flag=1; break; case 0x04://s5 set_mode ; if(set_mode>=3)set_mode=0; break; } } } //L1指示灯 void disp_LED() { if((temp*5.0/255)<=2||(temp*5.0/255)>=3) { if(led_flag) { LED|=1; }else{ LED&=~1; } } else if((temp*5.0/255)>2&&(temp*5.0/255)<3){ LED|=1; } } void main() { unsigned char str[35]; allinit(); Timer0Init(); UartInit(); Write_ADC(0x03);//rb2 while(1) { //读取rb2,电阻值,以及一个小数电压值和两个小数电压值 temp=Read_ADC(0x03); V_num1=(temp*5.0/255)*100; V_num2=temp*50.0/255; switch(set_mode) { case 0: table[0]=25; table[1]=16; table[2]=16; table[3]=16; table[4]=16; table[5]=V_num1/100 32; table[6]=V_num1/10; table[7]=V_num1; break; case 1: table[0]=25; table[1]=16; table[2]=16; table[3]=16; table[4]=16; table[5]=16; table[6]=V_num2/10 32; table[7]=V_num2; break; case 2: table[0]=16; table[1]=16; table[2]=16; table[3]=16; table[4]=16; table[5]=temp>100?temp/100:16; table[6]=temp>100?temp/100:16; table[6]=temp>100?temp/10:16; table[]=temp%10;
break;
}
if(send_flag)//串口
{
send_flag=0;
sprintf(str,"U:%4.2fV\r\n",v_num);//发送格式为:U:2.15V\r\n,uv大写,包含换行和回车
v_num=temp*5.0/255;
uart_sendstring(str);
Delay300ms();
Delay300ms();
if(rxc==1)
{
rxc=0;
ES=1;
}
}
disp_LED();
disp_key();//按键
}
}
2、iic
#include "reg52.h"
#include "intrins.h"
#define DELAY_TIME 5
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
void IIC_Delay(unsigned char i)
{
do{_nop_();}
while(i--);
}
//总线启动条件
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
//总线停止条件
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//等待应答
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(DELAY_TIME);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(DELAY_TIME);
}
return da;
}
//ADC
void Write_ADC(unsigned char add)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Stop();
}
unsigned char Read_ADC(unsigned char add)
{
unsigned char temp;
EA=0;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_Stop();
EA=1;
return temp;
}
#ifndef _IIC_H
#define _IIC_H
void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
//ADC
void Write_ADC(unsigned char add);
unsigned char Read_ADC(unsigned char add);
#endif
总结
就这四次模考来讲,考了基本的led灯,按键,数码管,时钟,eeprom,DA/AD,超声波,串口等。虽然其中超声波和串口都是国赛的考点,但是模考考了,这得重视,猜不准它不考。
其中按键考了长按中的长按超过要求时间后抬起才起作用。还有iic得多注意!!!感觉今年必考iic。DA必考!!!不考频率!!!