4T评测
记录自己的学习过程
以下代码仅供参考,有不对的请多多指教(西风模版)
main.c
#include
#include "init.h"
#include "key.h"
#include "led.h"
#include "seg.h"
#include "ds1302.h"
#include "iic.h"
//Key
unsigned char Key_vol,key_down,key_old;
//Seg
unsigned char Seg_pos;
unsigned char Seg_buf[]={10,10,10,10,10,10,10,10};
//Led
unsigned char ucLed[]={0,0,0,0,0,0,0,0};
unsigned char ucRtc[]={13,3,5};
//DA
unsigned char DA_freg;//DA的电压输出
unsigned int Freq;//频率
int Freq_Jaz_plus=0;
unsigned int time_1000ms;
int Freq_Jaz=0;//校准
unsigned int ChaoXian=2000;
unsigned char Seg_disp_mode;//0-频率 1-参数 2-时间 3-回显
bit Seg_disp_S5;//参数界面 0-超限参数 1-校准值
//回显界面 0-频率回显 1-时间回显
bit mode0_flag;//闪缩200ms标志位
bit error;//错误标志位
unsigned int Freq_max=0;
unsigned char ucRtc_max[]={0,0,0};
unsigned char Timer200ms;
void Key_proc()
{
if(time_1000ms%10)return;
Key_vol=Key_Read();
key_down=Key_vol&(key_old^Key_vol);
key_old=Key_vol;
switch(key_down)
{
case 4://界面切换
if(++Seg_disp_mode==4)Seg_disp_mode=0;
if((Seg_disp_mode==1)||(Seg_disp_mode==3))Seg_disp_S5=0;
break;
case 5://参数界面 0-超限参数 1-校准值
//回显界面 0-频率回显 1-时间回显
if(Seg_disp_mode==1)
{
Seg_disp_S5^=1;
}
if(Seg_disp_mode==3)
{
Seg_disp_S5^=1;
}
break;
case 8://超限参数:+1000
//校准值参数:+100
if(Seg_disp_mode==1)//参数界面下对子页面值修改
{
if(Seg_disp_S5==1)//校准值参数
{
Freq_Jaz=Freq_Jaz+100;
if(Freq_Jaz>900)Freq_Jaz=900;
}
else if(Seg_disp_S5==0)//超限参数
{
ChaoXian=ChaoXian+1000;
if(ChaoXian>9000)ChaoXian=9000;
}
}
break;
case 9://超限参数:-1000
//校准值参数:-100
if(Seg_disp_mode==1)//参数界面下对子页面值修改
{
if(Seg_disp_S5==1)//校准值参数
{
Freq_Jaz=Freq_Jaz-100;
if(Freq_Jaz<-900)Freq_Jaz=-900;
}
else if(Seg_disp_S5==0)//超限参数
{
ChaoXian=ChaoXian-1000;
if(ChaoXian<1000)ChaoXian=1000;
}
}
break;
}
}
void Seg_proc()
{
unsigned char i;
if(time_1000ms%500)return;
Read_Rtc(ucRtc);
Freq_Jaz_plus=Freq+Freq_Jaz;
if(Freq_max0)&&(Freq_Jaz<=900))
{
Seg_buf[4]=10;
Seg_buf[5]=Freq_Jaz/100%10;
Seg_buf[6]=Freq_Jaz/10%10;
Seg_buf[7]=Freq_Jaz%10;
}
else if(Freq_Jaz<0)
{
Seg_buf[4]=13;//-
Seg_buf[5]=(-Freq_Jaz)/100%10;
Seg_buf[6]=(-Freq_Jaz)/10%10;
Seg_buf[7]=(-Freq_Jaz)%10;
}
}
break;
case 2://时间界面
Seg_buf[2]=Seg_buf[5]=13;//-
Seg_buf[0]=ucRtc[0]/10%10;
Seg_buf[1]=ucRtc[0]%10;
Seg_buf[3]=ucRtc[1]/10%10;
Seg_buf[4]=ucRtc[1]%10;
Seg_buf[6]=ucRtc[2]/10%10;
Seg_buf[7]=ucRtc[2]%10;
break;
case 3://回显界面(0-频率 1-时间)
if(Seg_disp_S5==0)//回显子页面最大频率
{
Seg_buf[0]=14;//H
Seg_buf[1]=11;//F
Seg_buf[2]=10;
Seg_buf[3]=Freq_max/10000%10;
Seg_buf[4]=Freq_max/1000%10;
Seg_buf[5]=Freq_max/100%10;
Seg_buf[6]=Freq_max/10%10;
Seg_buf[7]=Freq_max%10;
i=3;
while(Seg_buf[i]==0)
{
Seg_buf[i]=10;
if(++i==7)break;
}
}
if(Seg_disp_S5==1)//回显子页面最大时间
{
Seg_buf[0]=14;//H
Seg_buf[1]=15;//A
Seg_buf[2]=ucRtc_max[0]/10%10;
Seg_buf[3]=ucRtc_max[0]%10;
Seg_buf[4]=ucRtc_max[1]/10%10;
Seg_buf[5]=ucRtc_max[1]%10;
Seg_buf[6]=ucRtc_max[2]/10%10;
Seg_buf[7]=ucRtc_max[2]%10;
}
break;
}
}
void Led_proc()
{
if(time_1000ms%2)return;
ucLed[0]=mode0_flag?!Seg_disp_mode:0;//0亮
if(error)
ucLed[1]=1;
else
ucLed[1]=mode0_flag?(Freq_Jaz_plus>ChaoXian):0;
}
void DA_proc()
{
float temp_da;
if(time_1000ms%150)return;
if(error)
{
DA_Read(0);
}
else if(Freq_Jaz_plus<=500)
{
DA_Read(1*51);
}
else if((Freq_Jaz_plus>500)&&(Freq_Jaz_plusChaoXian)
{
DA_Read(5*51);
}
}
void Timer1_Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x20; //设置定时初始值
TH1 = 0xD1; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1=1;
EA=1;
}
void Timer1_Server() interrupt 3
{
if(++Seg_pos==8)Seg_pos=0;
if(++Timer200ms==200)
{
Timer200ms=0;
mode0_flag^=1;
}
if(++time_1000ms==1000)
{
time_1000ms=0;
Freq=TH0<<8|TL0;
TH0=TL0=0;
}
Seg_disp(Seg_pos,Seg_buf[Seg_pos]);
Led_disp(Seg_pos,ucLed[Seg_pos]);
}
void Timer0_Init() //1毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x05;
TL0 = 0; //设置定时初始值
TH0 = 0; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA = 1; //使能定时器0中断
}
void main()
{
Sys_init();
Timer0_Init();
Timer1_Init();
Set_Rtc(ucRtc);
while(1)
{
Key_proc();
Seg_proc();
Led_proc();
DA_proc();
}
}
init.c
#include "init.h"
void Sys_init()
{
P0=0xFF;
P2=P2&0x1F|0x80;
P2=P2&0x1F;
P0=0x00;
P2=P2&0x1F|0xA0;
P2=P2&0x1F;
}
key.c
#include "key.h"
unsigned char Key_Read()
{
unsigned char temp=0;
P44=0;P42=1;P35=1;//P34=1;
if(P33==0)temp=4;
if(P32==0)temp=5;
if(P31==0)temp=6;
if(P30==0)temp=7;
P44=1;P42=0;P35=1;//P34=1;
if(P33==0)temp=8;
if(P32==0)temp=9;
if(P31==0)temp=10;
if(P30==0)temp=11;
P44=1;P42=1;P35=0;//P34=1;
if(P33==0)temp=12;
if(P32==0)temp=13;
if(P31==0)temp=14;
if(P30==0)temp=15;
return temp;
// P44=1;P42=1;P35=1;P34=0;
// if(P33==0)temp=4;
// if(P32==0)temp=4;
// if(P31==0)temp=4;
// if(P30==0)temp=4;
}
seg.c
#include "seg.h"
code unsigned char Seg_dula[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,
0x82,0xf8,0x80,0x90,0xff,0x8e,
0x8c,0xbf,0x89,0x88,0xc7};
void Seg_disp(unsigned char wela,unsigned char dula)
{
//消影
P0=0xFF;
P2=P2&0x1F|0xe0;
P2=P2&0x1F;
P0=0x01<
led.c
#include "led.h"
void Led_disp(unsigned char addr,bit enable)
{
static unsigned char temp=0x00;
static unsigned char temp_old=0xff;
if(enable)
temp=temp|(0x01<
ds1302.c
/* # DS1302代码片段说明
1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include "ds1302.h"
#include "intrins.h"
sbit RST = P1^3;
sbit SDA = P2^3;
sbit SCK = P1^7;
//
void Write_Ds1302(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++)
{
SCK = 0;
SDA = temp&0x01;
temp>>=1;
SCK=1;
}
}
//
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
{
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
Write_Ds1302(dat);
RST=0;
}
//
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
unsigned char i,temp=0x00;
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
for (i=0;i<8;i++)
{
SCK=0;
temp>>=1;
if(SDA)
temp|=0x80;
SCK=1;
}
RST=0; _nop_();
SCK=0; _nop_();
SCK=1; _nop_();
SDA=0; _nop_();
SDA=1; _nop_();
return (temp);
}
void Set_Rtc(unsigned char *ucRtc)
{
unsigned char i;
Write_Ds1302_Byte(0x8e,0x00);//关闭写保护
for(i=0;i<3;i++)
{
Write_Ds1302_Byte(0x84-i*2,ucRtc[i]/10<<4|ucRtc[i]%10);//10->16
}
Write_Ds1302_Byte(0x8e,0x80);
}
void Read_Rtc(unsigned char *ucRtc)
{
unsigned char temp,i;
for(i=0;i<3;i++)
{
temp=Read_Ds1302_Byte(0x85-i*2);//16->10
ucRtc[i]=temp/16*10+temp%16;
}
}
iic.c
/* # I2C代码片段说明
1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
#define DELAY_TIME 10
#include "iic.h"
#include "intrins.h"
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);
}
void DA_Read(unsigned char dat)
{
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x41);
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
}