在准备蓝桥杯单片机比赛,做了第一次省赛的题目,代码供大家参考,欢迎大家指出不足。
test.c
#include "stc15f2k60s2.h"
#include "iic.h"
#define uchar unsigned char
void show_moshi1();
void show_moshi2();
void show_moshi3();
void Write_24C02(uchar addr,uchar dat);
uchar Read_24C02(uchar addr);
uchar code SMG[]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//带小数点
uchar code SMG_dot[]={
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
//提示符字母
uchar code alphabet[]={
0xc1,0x8c,0xc8};
//PCF8591参数
uchar tmp;
int res;
//设置参数
int vpp=0;
//键盘值
int key_value;
//uchar key_stat=1;
//界面
uchar menu=1;
//计数值
int count=0;
int count_res=0;
//计数高低
bit high=0;
bit low=0;
uchar num=0;
//定时
uchar ms_50;
//LED模式
uchar led_moshi=0xff;
void delayms(unsigned int t){
uchar i;
while(t--) for(i=0;i<123;i++);
}
void HC138(uchar n){
switch(n){
case 4:
P2=(P2&0x1f)|0x80;
break;
case 5:
P2=(P2&0x1f)|0xa0;
break;
case 6:
P2=(P2&0x1f)|0xc0;
break;
case 7:
P2=(P2&0x1f)|0xe0;
break;
}
}
void show(uchar value,uchar pos){
//函数非内置SMG
HC138(6);
P0=0x01<<pos;
HC138(7);
P0=value;
}
void init(){
//关闭蜂鸣器
HC138(5);
P0=0x00;
HC138(4);
P0=0xff;
}
//==============PCF8591========================
void Read_PCF8591(){
double jingdu=500.0/255;
uchar n=5;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x03);
IIC_WaitAck();
IIC_Stop();
while(n--) show_moshi1();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
tmp=IIC_RecByte();
IIC_Stop();
res=tmp* jingdu;
}
void PCF8591(){
double jingdu=500.0/255;
uchar n=5;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x03);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
tmp=IIC_RecByte();
IIC_Stop();
res=tmp* jingdu;
}
//======================================
//================LED模块======================
void show_moshi1(){
show(alphabet[0],0);
delayms(10);
show(SMG_dot[res/100],5);
delayms(10);
show(SMG[(res/10)%10],6);
delayms(10);
show(SMG[res%10],7);
delayms(10);
}
void show_moshi2(){
show(alphabet[1],0);
delayms(10);
show(SMG_dot[vpp/10],5);
delayms(10);
show(SMG[vpp%10],6);
delayms(10);
show(SMG[0],7);
delayms(10);
}
void show_moshi3(){
show(alphabet[2],0);
delayms(10);
show(SMG[count_res/10],6);
delayms(10);
show(SMG[count_res%10],7);
delayms(10);
}
//======================================
//======
void scan_key(){
//处理键盘
uchar row;
P3=0x0f;
if((P33&P32)==0){
delayms(5);
if((P33&P32)==0){
if(P32==0) row=0;
else if(P33==0) row=1;
P3=0xf0;
if(row==0){
if((P35==0)&&menu==3){
//按键1
while(P35==0){
show_moshi3();}
count=0;
count_res=0;
}
else if((P34==0)&&menu==2) {
//按键2
while(P34==0){
show_moshi2();}
vpp-=5;
if(vpp<0) vpp=50;
}
}else if(row==1){
if(P35==0) {
//按键3
while(P35==0){
show_moshi1();}
menu++;
if(menu>3) {
menu=1;Write_24C02(0x01,vpp);}
}
else if((P34==0)&&menu==2) {
//按键4
while(P34==0){
show_moshi2();}
vpp+=5;
if(vpp>50) vpp=0;
}
}
}
}
}
//=====
void handle_count(){
double a=count/2.0;
count_res=a+0.5;
}
void init_timer(){
//定时器初始化
TMOD=0x00;
AUXR=0x3f;
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
ET1=1;
EA=1;
ET0=1;
TR0=1;
}
void counter()interrupt 1
{
if(res > vpp*10) {
high=1;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
TR1=0;
ms_50=0;
led_moshi=0xff;}
else if(res < vpp*10) {
low=1;
TR1=1;
}
if((high&low)==1){
count++;
high=0;
low=0;
}
}
void timer()interrupt 3
{
ms_50++;
if(ms_50==100){
ms_50=0;
led_moshi=0xfe;
}
}
//=============24C02=======================
void Write_24C02(uchar addr,uchar dat){
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
uchar Read_24C02(uchar addr){
uchar temp;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_SendAck(0);
IIC_Stop();
return temp;
}
//===========================================
void switch_moshi(){
//切换模式
if(menu==1){
Read_PCF8591();
show_moshi1();
}else if(menu ==2) {
show_moshi2();
}else if(menu ==3) {
show_moshi3();
}
}
void led(){
//led展示
if(count_res%2==1){
HC138(4);
P0=0xf7&led_moshi;
}else if(count_res%2==0){
HC138(4);
P0=0xff&led_moshi;
}
}
void main(){
init();
delayms(10);
init_timer();
vpp=Read_24C02(0x01);
while(1){
PCF8591();
handle_count();
switch_moshi();
scan_key();
led();
}
}
iic.c
/*
程序说明: IIC总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台 8051,12MHz
日 期: 2011-8-9
*/
#include "reg52.h"
#include "intrins.h"
#define DELAY_TIME 15
#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);
}
//发送应答
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit; // 0:应答,1:非应答
IIC_Delay(DELAY_TIME);
SCL = 1;
IIC_Delay(DELAY_TIME);
SCL = 0;
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;
}
iic.h
#ifndef _IIC_H
#define _IIC_H
//函数声明
void IIC_Start(void);
void IIC_Stop(void);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
bit IIC_WaitAck(void);
void IIC_SendAck(bit ackbit);
#endif
链接: https://pan.baidu.com/s/1fFh_vJJ-hQVp-I3GuxT59w
提取码: fwwb