一、模板罗列
1.1 iic.h
#ifndef __IIC_H__ #define __IIC_H__ #include <STC15F2K60S2.h> #include "intrins.h" sbit SD = P2^1; sbit SCL = P2^0; void IIC_Start(void); void IIC_Stop(void); bit IIC_WaitAck(void); void IIC_SendAck(bit ackbit); void IIC_SendByte(unsigned char byt); unsigned char IIC_RecByte(void); void Read_DAC(unsigned char date); unsigned char Write_ADC(unsigned char add); #endif
1.2 ds1302.h
#ifndef __DS1302_H__ #define __DS1302_H__ #include <STC15F2K60S2.h> #include <intrins.h> sbit SCK = P1^7; sbit SDA = P2^3; sbit RST = P1^3; void Write_Ds1302(unsigned char temp); void Write_Ds1302_Byte( unsigned char address,unsigned char dat ); unsigned char Read_Ds1302_Byte( unsigned char address ); #endif
1.3 onewire.h
#ifndef __ONEWIRE_H__ #define __ONEWIRE_H__ #include <STC15F2K60S2.h> sbit DQ = P1^4; unsigned char rd_temperature(void); #endif
1.4 main.c
#include <STC15F2K60S2.h> #include "onewire.h" #include "iic.h" #include "ds1302.h" #define uchar unsigned char #define uint unsigned int uchar SMG_duanma[10] = {0XC0, 0XF9, 0XA4, 0XB0, 0X99, 0X92, 0X82, 0XF8, 0X80, 0X90}; uchar yi,er,san,si,wu,liu,qi,ba; void SelectHC138(uchar channel); void initsys(); void DisplaySMG_Bit(uchar pos, uchar value); void Delay_one_ms_SMG(); void SMG_Display(); void Alone_Key(); void Delay_five_ms_Key(); void main() { yi = er = san = si = wu = liu = qi = ba = 0; initsys(); while(1) { Alone_Key(); SMG_Display(); } } // void SelectHC138(uchar channel) { switch(channel) { case 4: //LED 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 initsys() { SelectHC138(5); P0 = 0X00;//关闭蜂鸣器和继电器 SelectHC138(4); P0 = 0XFF; SelectHC138(6); P0 = 0XFF; SelectHC138(7); P0 = 0XFF; } void DisplaySMG_Bit(uchar pos, uchar value) { SelectHC138(6); P0 = 0X01 << pos; SelectHC138(7); P0 = value; } void Delay_one_ms_SMG() { uint j; for(j = 845; j > 0; j--); } void SMG_Display() { DisplaySMG_Bit(0, SMG_duanma[yi] & 0X80); Delay_one_ms_SMG(); DisplaySMG_Bit(1, SMG_duanma[er] - 0X80); Delay_one_ms_SMG(); DisplaySMG_Bit(2, SMG_duanma[san] | 0X80); Delay_one_ms_SMG(); DisplaySMG_Bit(3, SMG_duanma[si]); Delay_one_ms_SMG(); DisplaySMG_Bit(4, SMG_duanma[wu]); Delay_one_ms_SMG(); DisplaySMG_Bit(5, SMG_duanma[liu]); Delay_one_ms_SMG(); DisplaySMG_Bit(6, SMG_duanma[qi]); Delay_one_ms_SMG(); DisplaySMG_Bit(7, SMG_duanma[ba]); Delay_one_ms_SMG(); } void Delay_five_ms_Key() { uint i,j; for(i = 0;i < 5;i++) for(j = 845; j > 0;j--); } void Alone_Key() { //S7 if(P30 == 0) { Delay_five_ms_Key(); if(P30 == 0) { yi = 1; } while(!P30); } //S6 if(P31 == 0) { Delay_five_ms_Key(); if(P31 == 0) { er = 1; } while(!P31); } //S5 if(P32 == 0) { Delay_five_ms_Key(); if(P32 == 0) { san = 1; } while(!P32); } //S4 if(P33 == 0) { Delay_five_ms_Key(); if(P33 == 0) { si = 1; } while(!P33); } } void Timer0Init(void) //1毫秒@12.000MHz { AUXR |= 0x80; //定时器时钟1T模式 TMOD &= 0xF0; //设置定时器模式 TL0 = 0x20; //设置定时初值 TH0 = 0xD1; //设置定时初值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 } void Timer0Service() interrupt 1 { }
1.5 onewire.c
#include "onewire.h" //单总线内部延时函数 void Delay_OneWire(unsigned int t) { t = t * 12; while(t--); } //单总线写操作 void Write_DS18B20(unsigned char dat) { unsigned char i; for(i=0;i<8;i++) { DQ = 0; DQ = dat&0x01; Delay_OneWire(5); DQ = 1; dat >>= 1; } Delay_OneWire(5); } //单总线读操作 unsigned char Read_DS18B20(void) { unsigned char i; unsigned char dat; for(i=0;i<8;i++) { DQ = 0; dat >>= 1; DQ = 1; if(DQ) { dat |= 0x80; } Delay_OneWire(5); } return dat; } //DS18B20初始化 bit init_ds18b20(void) { bit initflag = 0; DQ = 1; Delay_OneWire(12); DQ = 0; Delay_OneWire(80); DQ = 1; Delay_OneWire(10); initflag = DQ; Delay_OneWire(5); return initflag; } float Get_temp() { float temp; unsigned char hig,low; init_ds18b20(); Write_DS18B20(0XCC); Write_DS18B20(0X88); init_ds18b20(); Write_DS18B20(0XCC); Write_DS18B20(0XEE); low = Read_DS18B20(); hig = Read_DS18B20(); temp = (hig<<8|low)*0.0625; return temp; } //temp = (int)Get_temp() //shi = temp / 10;
1.4 iic.c
#include "iic.h" #define DELAY_TIME 5 //I2C总线内部延时函数 void IIC_Delay(unsigned char i) { do{_nop_();} while(i--); } //I2C总线启动信号 void IIC_Start(void) { SD = 1; SCL = 1; IIC_Delay(DELAY_TIME); SD = 0; IIC_Delay(DELAY_TIME); SCL = 0; } //I2C总线停止信号 void IIC_Stop(void) { SD = 0; SCL = 1; IIC_Delay(DELAY_TIME); SD = 1; IIC_Delay(DELAY_TIME); } //发送应答或非应答信号 void IIC_SendAck(bit ackbit) { SCL = 0; SD = ackbit; IIC_Delay(DELAY_TIME); SCL = 1; IIC_Delay(DELAY_TIME); SCL = 0; SD = 1; IIC_Delay(DELAY_TIME); } //等待应答 bit IIC_WaitAck(void) { bit ackbit; SCL = 1; IIC_Delay(DELAY_TIME); ackbit = SD; 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) SD = 1; else SD = 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(SD) da |= 1; SCL = 0; IIC_Delay(DELAY_TIME); } return da; } unsigned char Write_ADC(unsigned char add) { unsigned char dat; IIC_Start(); IIC_SendByte(0X90); IIC_WaitAck(); IIC_SendByte(add); IIC_WaitAck(); IIC_Start(); IIC_SendByte(0X91); IIC_WaitAck(); dat = IIC_RecByte(); IIC_SendAck(1); IIC_Stop(); return dat; } void Read_DAC(unsigned char date) { IIC_Start(); IIC_SendByte(0X90); IIC_WaitAck(); IIC_SendByte(0X40); IIC_WaitAck(); IIC_SendByte(date); IIC_WaitAck(); IIC_Stop(); } void EEPROM_write(unsigned char add,unsigned char date) { IIC_Start(); IIC_SendByte(0XA0); IIC_WaitAck(); IIC_SendByte(add); IIC_WaitAck(); IIC_SendByte(date); IIC_WaitAck(); IIC_Stop(); IIC_Delay(5); } unsigned char EEPROM_read(unsigned char add) { unsigned char dat; IIC_Start(); IIC_SendByte(0XA0); IIC_WaitAck(); IIC_SendByte(add); IIC_WaitAck(); IIC_Start(); IIC_SendByte(0XA1); IIC_WaitAck(); dat = IIC_RecByte(); IIC_SendAck(1); IIC_Stop(); return dat; }
1.4 ds1302.c
#include "ds1302.h" #define DecToBCD(dec) (dec/10*16)+(dec%10) #define BCDToDec(BCD) (BCD/16*10)+(BCD%16) //写字节 void Write_Ds1302(unsigned char temp) { unsigned char i; for (i=0;i<8;i++) { SCK = 0; SDA = temp&0x01; temp>>=1; SCK=1; } } //向DS1302寄存器写入数据 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; } //从DS1302寄存器读出数据 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 Init_DS1302() { unsigned char i,add; add = 0X80; Write_Ds1302_Byte(0X8E, 0X00); for(i = 0; i < 7; i++) { Write_Ds1302_Byte(add,DecToBCD(shijian[i])); add = add + 2; } } void Read_DS1302() { unsigned char i,add; add = 0X81; for(i = 0; i < 7; i++) { shijian[i] = BCDToDec(Read_Ds1302_Byte()); add = add + 2; } }
二、一些技巧总结
1.共阳数码管,BCD数字-0X80就是带小数点,共阴就是|0X80
2.iic和ds1302同时使用时,注意SDA的重复定义
3.底层逻辑代码,一定要多练
4.iic:ADC/DAC、EEPROM
5.onewire:温度
6.ds1302:时钟
7.注意12MHz
8.读温度和iic,的精度,可以用float接
//ds1302用 #define DecToBCD(dec) (dec/10*16)+(dec%10) //十进制转十六进制 #define BCDToDec(BCD) (BCD/16*10)+(BCD%16) //十六进制转十进制
EEPROM有7个地址,每个地址有8位
三、心得
对于蓝桥杯,回忆了好多事情,一点一点学吧,真的,只要每天学一点,就可以很厉害,博主是没有买课,各种嫖(比我同学那种买课的,我就像野路子,hhhh~),从学长那嫖的一种网课,加上B站的小蜜蜂。博主也是这样一路学过来,之后开始写省赛题,一开始有畏难心理,之后就慢慢克服了(一定要先自己独立写,一般都可以自己写出来的)。
自己的模板有了,可以用,但考试前一定要多练,多练!,一定要!还要EEPROM、DA/AD,等等小函数,考前也一定要多练!!!
对于买课呢,也挺好,是个正规路子,我同学都90-110不等,所以自己看情况吧
对于这次的比赛呢,超声波模块我是真的没想到,哈哈哈哈哈,直接放弃,别的模块都尽全力去写。
对于客观题呢,看一遍历届赛题吧,虽然感觉没多大用,但是聊胜于无吧,模电数电一定要认真学,还有官方提供的手册,博主也不知道该怎么看,哈哈哈哈,比较菜,客观题好像可以从里面找答案。
如果有时间,我说有时间的话,可以对驱动进行更深度的理解,了解原理。博主之后有时间会再看看
此次蓝桥之后,博主就准备进攻STM32了,应该再学期吧,不知道有没有时间,听说课很多。