设计要求
通过PCF8591的ADC通道测量电位器RB2的输出电压,并使用套件上提供的USB转串口功能,完成下列程序设计要求。
串口每次接收包含5个字符的字符串,
1)若接收的5个字符中有字符'a'或'A',则数码管显示一位小数电压值,指示灯L1点亮;
数码管显示格式如下:

电压:2.4V
2)若接收的5个字符中有字符'1'或'#',则数码管显示两位小数电压值,指示灯L2点亮;
数码管显示格式如下:

电压:2.41V
3)若不属于以上两种情况,则数码管显示整数电压值,指示灯全部熄灭。
数码管显示格式如下:

电压:2V
备注:
单片机IRC振荡器频率设置为12MHz。
键盘模式:BTN;扩展模式:IO模式
串口波特率:9600bps
上电指示灯均处于熄灭状态,数码管默认显示整数。
数码管最高位固定显示字符'U'。
代码
sys.h
cpp
#ifndef __SYS_H__
#define __SYS_H__
#include <STC15F2K60S2.H>
//iic.c
void get_Vrb2();
//sys.c
extern unsigned char Seg_Buff[8];
extern unsigned char UI;
extern float Vrb2;
void init74hc138(unsigned char n);
void init();
void Seg_Loop();
void seg_ui();
#endif
main.c
cpp
#include "sys.h"
bit flag1=0;
bit flag2=0;
bit flag3=0;
unsigned char str[6];
void Timer0_Isr(void) interrupt 1
{
static unsigned char count1=0;
static unsigned int count2=0;
count1++;
count2++;
if(count1==2){
count1=0;
flag1=1;
}
if(count2==1000){
count2=0;
flag2=1;
}
}
void Timer0_Init(void) //100微秒@12.000MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x50; //设置定时初始值
TH0 = 0xFB; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
EA=1;
}
void UartInit(void) //[email protected]
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器时钟1T模式
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设置定时器模式
TL1 = 0xC7; //设置定时初始值
TH1 = 0xFE; //设置定时初始值
ET1 = 0; //禁止定时器中断
TR1 = 1; //定时器1开始计时
ES=1;
EA=1;
}
unsigned char choose_ui(unsigned char *str){
unsigned char i;
for(i=0;i<5;i++){
if(str[i]=='A'||str[i]=='a') return 1;
if(str[i]=='1'||str[i]=='#') return 2;
}
return 0;
}
void main(){
init();
Timer0_Init();
UartInit();
while(1){
if(flag1){
flag1=0;
Seg_Loop();
}
if(flag2){
flag2=0;
get_Vrb2();
seg_ui();
}
if(flag3){
flag3=0;
UI=choose_ui(str);
seg_ui();
}
}
}
void uart() interrupt 4
{
static unsigned char i=0;
if(RI){
RI=0;
str[i]=SBUF;
i++;
if(i==5){
i=0;
flag3=1;
}
}
}
sys.c
cpp
#include "sys.h"
code unsigned char Seg_Table[]={
0xC0, 0xF9 ,0xA4, 0xB0, 0x99 ,0x92 ,0x82 ,0xF8, 0x80 ,0x90,
0xc1,//U 10
0xff //熄灭 11
};
unsigned char Seg_Buff[8]={11,11,11,11,11,11,11,11};
unsigned char UI=0;
float Vrb2;
void init74hc138(unsigned char n){
P2=(P2&0x1f)|(n<<5);
P2&=0x1f;
}
void init(){
P0=0x00;
init74hc138(5);
P0=0xff;
init74hc138(4);
}
void led(unsigned char addr){
P0=~(0x01<<(addr-1));
init74hc138(4);
}
void seg(unsigned char addr,num){
P0=0xff;
init74hc138(7);
P0=0x01<<addr;
init74hc138(6);
P0=Seg_Table[num];
if(UI!=0){
if(UI==1){
if(addr==6)P0&=0x7f;
}else if(UI==2){
if(addr==5)P0&=0x7f;
}
}
init74hc138(7);
}
void Seg_Loop(){
static unsigned char i=0;
seg(i,Seg_Buff[i]);
i++;
if(i==8)i=0;
}
void ui0(){
Seg_Buff[7]=(int)(Vrb2+0.005)%10;
Seg_Buff[6]=11;
Seg_Buff[5]=11;
}
void ui1(){
Seg_Buff[7]=(int)(Vrb2*10+0.05)%10;
Seg_Buff[6]=(int)(Vrb2+0.005)%10;
Seg_Buff[5]=11;
}
void ui2(){
Seg_Buff[7]=(int)(Vrb2*100+0.5)%10;
Seg_Buff[6]=(int)(Vrb2*10+0.05)%10;
Seg_Buff[5]=(int)(Vrb2+0.005)%10;
}
void seg_ui(){
Seg_Buff[0]=10;
switch(UI){
case 0:ui0();led(9);break;
case 1:ui1();led(1);break;
case 2:ui2();led(2);break;//led(9)定为全部熄灭
}
}
iic.c
cpp
#include "sys.h"
#include "intrins.h"
#define DELAY_TIME 10
sbit scl=P2^0;
sbit sda=P2^1;
//
static void I2C_Delay(unsigned char n)
{
do
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
while(n--);
}
//
void I2CStart(void)
{
sda = 1;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 0;
I2C_Delay(DELAY_TIME);
scl = 0;
}
//
void I2CStop(void)
{
sda = 0;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 1;
I2C_Delay(DELAY_TIME);
}
//
void I2CSendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++){
scl = 0;
I2C_Delay(DELAY_TIME);
if(byt & 0x80){
sda = 1;
}
else{
sda = 0;
}
I2C_Delay(DELAY_TIME);
scl = 1;
byt <<= 1;
I2C_Delay(DELAY_TIME);
}
scl = 0;
}
//
unsigned char I2CReceiveByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++){
scl = 1;
I2C_Delay(DELAY_TIME);
da <<= 1;
if(sda)
da |= 0x01;
scl = 0;
I2C_Delay(DELAY_TIME);
}
return da;
}
//
unsigned char I2CWaitAck(void)
{
unsigned char ackbit;
scl = 1;
I2C_Delay(DELAY_TIME);
ackbit = sda;
scl = 0;
I2C_Delay(DELAY_TIME);
return ackbit;
}
//
void I2CSendAck(unsigned char ackbit)
{
scl = 0;
sda = ackbit;
I2C_Delay(DELAY_TIME);
scl = 1;
I2C_Delay(DELAY_TIME);
scl = 0;
sda = 1;
I2C_Delay(DELAY_TIME);
}
unsigned char adc(unsigned char addr){
unsigned char temp;
EA=0;
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
temp=I2CReceiveByte();
I2CSendAck(1);
I2CStop();
EA=1;
return temp;
}
void get_Vrb2(){
Vrb2=(float)adc(3)/255*5.0;
}
测评结果
