硬件有DS1302,0.96OLED、TEA5767
驱动程序如下
#include "ds1302.h"
#include "delay.h"
extern unsigned char Time[8], TimeBuff[8];
unsigned char TimeBuff1[8];
void DS1302_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; // 写模式
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = DS1302_CLK|DS1302_DAT|DS1302_RST;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
DS_DAT_Set(); //DAT脚置高
DS_RST_Clr(); //RST脚置低
DS_CLK_Clr(); //SCK脚置低
}
void DS1302_write_byte(u8 addr, u8 data) //无论写还是读都必须先写入一字节的地址,然后读一字节,所以GPIO模式必须不停切换
{
u8 i;
DS_RST_Clr();
delay_us(10);
DS_RST_Set(); //启动DS1302总线
//写入目标地址:addr
addr = addr & 0xFE; //最低位置零,寄存器0位为0时写,为1时读
Dat_Out();
for (i = 0; i < 8; i ++) {
if (addr & 0x01) {
DS_DAT_Set();
}
else {
DS_DAT_Clr();
}
DS_CLK_Set(); //产生时钟
delay_us(10);
DS_CLK_Clr();
addr = addr >> 1;
}
//写入数据:d
for (i = 0; i < 8; i ++) {
if (data & 0x01) {
DS_DAT_Set();
}
else {
DS_DAT_Clr();
}
DS_CLK_Set(); //产生时钟
delay_us(10);
DS_CLK_Clr();
data = data >> 1;
}
DS_RST_Clr(); //停止DS1302总线
}
u8 DS1302_read_byte(u8 addr)
{
u8 i, data=0;
DS_RST_Clr();
delay_us(10);
DS_RST_Set(); //启动DS1302总线
//写入目标地址:addr
addr = addr | 0x01; //最低位置零,寄存器0位为0时写,为1时读
Dat_Out();
for(i=0; i<8; i++){
if(addr & 0x01)
DS_DAT_Set();
else
DS_DAT_Clr();
DS_CLK_Set(); //产生时钟信号
delay_us(10);
DS_CLK_Clr();
addr >>= 1;
}
Dat_In();
for (i=0; i<8; i++) {
data = data >> 1;
if (GPIO_ReadInputDataBit(GPIOB,DS1302_DAT)) data |= 0x80;
else data &= 0x7F;
DS_CLK_Set(); //产生时钟信号
delay_us(10);
DS_CLK_Clr();
}
DS_RST_Clr();
return data;
}
void DS1302_write_time(void) //仅支持设置时和分,每次设置后秒自动归零
{
unsigned char Hour, Min;
Hour = (TimeBuff[0]/10)*16 + TimeBuff[0]%10; //写入的数据转换为16进制数值
Min = (TimeBuff[1]/10)*16 + TimeBuff[1]%10;
DS1302_write_byte(ds1302_control_add,0x00); //关闭写保护
DS1302_write_byte(ds1302_hr_add,Hour); //时
DS1302_write_byte(ds1302_min_add,Min); //分
DS1302_write_byte(ds1302_sec_add,0x00); //秒归零
DS1302_write_byte(ds1302_control_add,0x80); //打开写保护
}
void DS1302_read_time(void) //读取时、分、秒
{
TimeBuff1[0] = DS1302_read_byte(ds1302_hr_add); //时
TimeBuff1[1] = DS1302_read_byte(ds1302_min_add); //分
TimeBuff1[2] = (DS1302_read_byte(ds1302_sec_add))&0x7f; //秒
Time[0]=(TimeBuff1[1]>>4);
Time[1]=(TimeBuff1[1]&0x0f);
Time[2]=(TimeBuff1[2]>>4);
Time[3]=(TimeBuff1[2]&0x0f);
Time[4]=(TimeBuff1[0]>>4);
Time[5]=(TimeBuff1[0]&0x0f);
}
void Dat_Out(void){ //DAT设置为输出
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = DS1302_DAT;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void Dat_In(void){ //DAT设置为输入
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = DS1302_DAT;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
OLED。c
#include "oled.h"
#include "stdlib.h"
#include "oledfont.h"
#include "delay.h"
u8 OLED_GRAM[144][8];
//extern unsigned char Brightness;
//反显函数
void OLED_ColorTurn(u8 i)
{
if(i==0)
{
OLED_WR_Byte(0xA6,OLED_CMD);//正常显示
}
if(i==1)
{
OLED_WR_Byte(0xA7,OLED_CMD);//反色显示
}
}
//屏幕旋转180度
void OLED_DisplayTurn(u8 i)
{
if(i==0)
{
OLED_WR_Byte(0xC8,OLED_CMD);//正常显示
OLED_WR_Byte(0xA1,OLED_CMD);
}
if(i==1)
{
OLED_WR_Byte(0xC0,OLED_CMD);//反转显示
OLED_WR_Byte(0xA0,OLED_CMD);
}
}
//延时
void IIC_delay(void)
{
u8 t=10;
while(t--);
}
//起始信号
void I2C_Start(void)
{
OLED_SDA_Set();
OLED_SCL_Set();
IIC_delay();
OLED_SDA_Clr();
IIC_delay();
OLED_SCL_Clr();
IIC_delay();
}
//结束信号
void I2C_Stop(void)
{
OLED_SCL_Clr();
OLED_SDA_Clr();
IIC_delay();
OLED_SCL_Set();
IIC_delay();
OLED_SDA_Set();
}
//等待信号响应
void I2C_WaitAck(void) //测数据信号的电平
{
OLED_SDA_Set();
IIC_delay();
OLED_SCL_Set();
IIC_delay();
OLED_SCL_Clr();
IIC_delay();
}
//写入一个字节
void Send_Byte(u8 dat)
{
u8 i;
for(i=0;i<8;i++)
{
if(dat&0x80)//将dat的8位从最高位依次写入
{
OLED_SDA_Set();
}
else
{
OLED_SDA_Clr();
}
IIC_delay();
OLED_SCL_Set();
IIC_delay();
OLED_SCL_Clr();//将时钟信号设置为低电平
dat<<=1;
}
}
//发送一个字节
//mode:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(u8 dat,u8 mode)
{
I2C_Start();
Send_Byte(0x78);
I2C_WaitAck();
if(mode){Send_Byte(0x40);}
else{Send_Byte(0x00);}
I2C_WaitAck();
Send_Byte(dat);
I2C_WaitAck();
I2C_Stop();
}
//开启OLED显示
void OLED_DisPlay_On(void)
{
OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵使能
OLED_WR_Byte(0x14,OLED_CMD);//开启电荷泵
OLED_WR_Byte(0xAF,OLED_CMD);//点亮屏幕
}
//关闭OLED显示
void OLED_DisPlay_Off(void)
{
OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵使能
OLED_WR_Byte(0x10,OLED_CMD);//关闭电荷泵
OLED_WR_Byte(0xAE,OLED_CMD);//关闭屏幕
}
//更新显存到OLED
void OLED_Refresh(void)
{
u8 i,n;
for(i=0;i<8;i++)
{
OLED_WR_Byte(0xb0+i,OLED_CMD); //设置行起始地址
OLED_WR_Byte(0x00,OLED_CMD); //设置低列起始地址
OLED_WR_Byte(0x10,OLED_CMD); //设置高列起始地址
I2C_Start();
Send_Byte(0x78);
I2C_WaitAck();
Send_Byte(0x40);
I2C_WaitAck();
for(n=0;n<130;n++)
{
Send_Byte(OLED_GRAM[n][i]);
I2C_WaitAck();
}
I2C_Stop();
}
}
//清屏函数
void OLED_Clear(void)
{
u8 i,n;
for(i=0;i<8;i++)
{
for(n=0;n<130;n++)
{
OLED_GRAM[n][i]=0;//清除所有数据
}
}
OLED_Refresh();//更新显示
}
//画点
//x:0~127
//y:0~63
//t:1 填充 0,清空
void OLED_DrawPoint(u8 x,u8 y,u8 t)
{
u8 i,m,n;
i=y/8; //横向页
m=y%8; //纵向位置
n=1<<m;
if(t){OLED_GRAM[x][i]|=n;}
else
{
OLED_GRAM[x][i]=~OLED_GRAM[x][i];
OLED_GRAM[x][i]|=n;
OLED_GRAM[x][i]=~OLED_GRAM[x][i];
}
}
void Clear_XY(u8 x1,u8 y1,u8 x2,u8 y2)
{
u8 temp = y1;
while(x1<x2)
{
while(y1<y2)
{
OLED_DrawPoint(x1,y1,0);
y1++;
}
y1=temp;
x1++;
}
}
//画线
//x1,y1:起点坐标
//x2,y2:结束坐标
void OLED_DrawLine(u8 x1,u8 y1,u8 x2,u8 y2,u8 mode)
{
u16 t;
int xerr=0,yerr=0,delta_x,delta_y,distance;
int incx,incy,uRow,uCol;
delta_x=x2-x1; //计算坐标增量
delta_y=y2-y1;
uRow=x1;//画线起点坐标
uCol=y1;
if(delta_x>0)incx=1; //设置单步方向
else if (delta_x==0)incx=0;//垂直线
else {incx=-1;delta_x=-delta_x;}
if(delta_y>0)incy=1;
else if (delta_y==0)incy=0;//水平线
else {incy=-1;delta_y=-delta_x;}
if(delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴
else distance=delta_y;
for(t=0;t<distance+1;t++)
{
OLED_DrawPoint(uRow,uCol,mode);//画点
xerr+=delta_x;
yerr+=delta_y;
if(xerr>distance)
{
xerr-=distance;
uRow+=incx;
}
if(yerr>distance)
{
yerr-=distance;
uCol+=incy;
}
}
}
//x,y:圆心坐标
//r:圆的半径
void OLED_DrawCircle(u8 x,u8 y,u8 r)
{
int a, b,num;
a = 0;
b = r;
while(2 * b * b >= r * r)
{
OLED_DrawPoint(x + a, y - b,1);
OLED_DrawPoint(x - a, y - b,1);
OLED_DrawPoint(x - a, y + b,1);
OLED_DrawPoint(x + a, y + b,1);
OLED_DrawPoint(x + b, y + a,1);
OLED_DrawPoint(x + b, y - a,1);
OLED_DrawPoint(x - b, y - a,1);
OLED_DrawPoint(x - b, y + a,1);
a++;
num = (a * a + b * b) - r*r;//计算画的点离圆心的距离
if(num > 0)
{
b--;
a--;
}
}
}
//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//size1:选择字体 6x8/6x12/8x16/12x24
//mode:0,反色显示;1,正常显示
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size1,u8 mode)
{
u8 i,m,temp,size2,chr1;
u8 x0=x+2,y0=y;
x += 2;
if(size1==8)size2=6;
else size2=(size1/8+((size1%8)?1:0))*(size1/2); //得到字体一个字符对应点阵集所占的字节数
chr1=chr-' '; //计算偏移后的值
for(i=0;i<size2;i++)
{
if(size1==8)
{temp=asc2_0806[chr1][i];} //调用0806字体
//else if(size1==12)
//{temp=asc2_1206[chr1][i];} //调用1206字体
else if(size1==16)
{temp=asc2_1608[chr1][i];} //调用1608字体
// else if(size1==24)
//{temp=asc2_2412[chr1][i];} //调用2412字体
else return;
for(m=0;m<8;m++)
{
if(temp&0x01)OLED_DrawPoint(x,y,mode);
else OLED_DrawPoint(x,y,!mode);
temp>>=1;
y++;
}
x++;
if((size1!=8)&&((x-x0)==size1/2))
{x=x0;y0=y0+8;}
y=y0;
}
}
//显示字符串
//x,y:起点坐标
//size1:字体大小
//*chr:字符串起始地址
//mode:0,反色显示;1,正常显示
void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 size1,u8 mode)
{
if(y>63|(int)y<0) return;
x+=2;
while((*chr>=' ')&&(*chr<='~'))//判断是不是非法字符!
{
OLED_ShowChar(x,y,*chr,size1,mode);
if(size1==8)x+=6;
else x+=size1/2;
chr++;
}
}
//m^n
u32 OLED_Pow(u8 m,u8 n)
{
u32 result=1;
while(n--)
{
result*=m;
}
return result;
}
//显示数字
//x,y :起点坐标
//num :要显示的数字
//len :数字的位数
//size:字体大小
//mode:0,反色显示;1,正常显示
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size1,u8 mode)
{
u8 t,temp,m=0;
x += 2;
if(size1==8)m=2;
for(t=0;t<len;t++)
{
temp=(num/OLED_Pow(10,len-t-1))%10;
if(temp==0)
{
OLED_ShowChar(x+(size1/2+m)*t,y,'0',size1,mode);
}
else
{
OLED_ShowChar(x+(size1/2+m)*t,y,temp+'0',size1,mode);
}
}
}
//显示汉字
//x,y:起点坐标
//num:汉字对应的序号
//mode:0,反色显示;1,正常显示
void OLED_ShowChinese(u8 x,u16 y,u8 num,u8 size1,u8 mode)
{
u8 m,temp;
u8 x0,y0=y;
u16 i,size3;
if(y>48||(int)y<0) return;
size3=(size1/8+((size1%8)?1:0))*size1; //得到字体一个字符对应点阵集所占的字节数
x += 2;
x0 = x;
for(i=0;i<size3;i++)
{
if(size1==16)
{temp=Hzk1[num][i];}//调用16*16字体
//else if(size1==24)
//{temp=Hzk2[num][i];}//调用24*24字体
// else if(size1==32)
//{temp=Hzk3[num][i];}//调用32*32字体
//else if(size1==64)
//{temp=Hzk4[num][i];}//调用64*64字体
else return;
for(m=0;m<8;m++)
{
if(temp&0x01)OLED_DrawPoint(x,y,mode);
else OLED_DrawPoint(x,y,!mode);
temp>>=1;
y++;
}
x++;
if((x-x0)==size1)
{x=x0;y0=y0+8;}
y=y0;
}
}
//num 显示汉字的个数
//space 每一遍显示的间隔
//mode:0,反色显示;1,正常显示
void OLED_ScrollDisplay(u8 num,u8 space,u8 mode)
{
u8 i,n,t=0,m=0,r;
while(1)
{
if(m==0)
{
OLED_ShowChinese(128,24,t,16,mode); //写入一个汉字保存在OLED_GRAM[][]数组中
t++;
}
if(t==num)
{
for(r=0;r<16*space;r++) //显示间隔
{
for(i=1;i<144;i++)
{
for(n=0;n<8;n++)
{
OLED_GRAM[i-1][n]=OLED_GRAM[i][n];
}
}
OLED_Refresh();
}
t=0;
}
m++;
if(m==16){m=0;}
for(i=1;i<144;i++) //实现左移
{
for(n=0;n<8;n++)
{
OLED_GRAM[i-1][n]=OLED_GRAM[i][n];
}
}
OLED_Refresh();
}
}
//x,y:起点坐标
//sizex,sizey,图片长宽
//BMP[]:要写入的图片数组
//mode:0,反色显示;1,正常显示
void OLED_ShowPicture(u8 x,u8 y,u8 sizex,u8 sizey,u8 BMP[],u8 mode)
{
u16 j=0;
u8 i,n,temp,m;
u8 x0,y0=y;
x += 2;
x0 = x;
sizey=sizey/8+((sizey%8)?1:0);
for(n=0;n<sizey;n++)
{
for(i=0;i<sizex;i++)
{
temp=BMP[j];
j++;
for(m=0;m<8;m++)
{
if(temp&0x01)OLED_DrawPoint(x,y,mode);
else OLED_DrawPoint(x,y,!mode);
temp>>=1;
y++;
}
x++;
if((x-x0)==sizex)
{
x=x0;
y0=y0+8;
}
y=y0;
}
}
}
//OLED的初始化
void OLED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能A端口时钟
GPIO_InitStructure.GPIO_Pin = SCL|DIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA0,1
GPIO_SetBits(GPIOA,SCL|DIN);
OLED_RES_Clr();
delay_ms(200);
OLED_RES_Set();
OLED_DisplayTurn(0);
OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
OLED_WR_Byte(0x40,OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
// OLED_WR_Byte(0x05+(Brightness-1)*32,OLED_CMD);// Set SEG Output Current Brightness
OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display
OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
OLED_WR_Byte(0x00,OLED_CMD);//-not offset
OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
OLED_WR_Byte(0x12,OLED_CMD);
OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh
OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
OLED_WR_Byte(0x02,OLED_CMD);//
OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)
OLED_Clear();
OLED_WR_Byte(0xAF,OLED_CMD);
}
tea5767.c
# include "tea5657.h"
#include "oled.h"
extern unsigned char radio_write_data[5],Laud;
extern unsigned char radio_read_data[5];
extern unsigned int default_pll;
extern u32 Frequence;
extern unsigned char KeyState[3];
void Tea_Init(char state){
if(state){
GPIO_InitTypeDef GPIO_InitStructure; // 写模式
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin =Tea_CLK|Tea_SDA;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
else // 读模式
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = Tea_SDA;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin =Tea_CLK;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
}
void Tea_IIC_Start(void)
{
Tea_SDA_Set();
Tea_IIC_delay();
Tea_CLK_Set();
Tea_IIC_delay();
Tea_SDA_Clr();
Tea_IIC_delay();
Tea_CLK_Clr();
Tea_IIC_delay();
}
void Tea_IIC_Stop(void)
{
Tea_CLK_Clr();
Tea_IIC_delay();
Tea_SDA_Clr();
Tea_IIC_delay();
Tea_CLK_Set();
Tea_IIC_delay();
Tea_SDA_Set();
Tea_IIC_delay();
}
void Tea_IIC_delay(void)
{
u8 t=100;
while(t--);
}
void Mcu_I2C_Ack(void)//测数据信号的电平
{
Tea_SDA_Clr();
Tea_IIC_delay();
Tea_CLK_Set();
Tea_IIC_delay();
Tea_CLK_Clr();
Tea_IIC_delay();
Tea_SDA_Set();
Tea_IIC_delay();
}
char IIC2_Test_ACK(void)
{
char ErrorBit;
Tea_SDA_Set();
Tea_IIC_delay();
Tea_CLK_Set();
Tea_IIC_delay();
ErrorBit=GPIO_ReadInputDataBit(GPIOB,Tea_SDA);
Tea_IIC_delay();
Tea_CLK_Clr();
return ErrorBit;
}
void Write_Tea_Byte(u8 dat)
{
u8 i;
for(i=0;i<8;i++)
{
if(dat&0x80)//将dat的8位从最高位依次写入
{
Tea_SDA_Set();
}
else
{
Tea_SDA_Clr();
}
Tea_IIC_delay();
Tea_CLK_Set();
Tea_IIC_delay();
Tea_CLK_Clr();//将时钟信号设置为低电平
dat<<=1;
}
}
void Volume_Write(u8 Vol)
{
u8 Temp_H,Temp_L;
Temp_H=(Vol/10)|0xe0;
Temp_L=(Vol%10)|0xd0;
Tea_IIC_Start(); //双声道同时改变,-10dB/Step,
Write_Tea_Byte(0x88); //写PT2257地址
IIC2_Test_ACK();
Write_Tea_Byte(Temp_H);
Mcu_I2C_Ack();
Write_Tea_Byte(Temp_L);
Mcu_I2C_Ack();
Tea_IIC_Stop();
}
u8 Read_Tea_Byte(void)//IIC读一个字节
{
u8 i,Data=0;
Tea_SDA_Set();
for(i=8;i>0;i--)
{
Data<<=1;
Tea_CLK_Clr();
Tea_IIC_delay();
Tea_CLK_Set();
Tea_IIC_delay();
Data|=GPIO_ReadInputDataBit(GPIOB,Tea_SDA); //读管脚的状态
}
Tea_CLK_Clr();
Tea_IIC_delay();
return(Data);
}
void radio_write(void)
{
unsigned char i;
Tea_IIC_Start();
Write_Tea_Byte(0xc0); //TEA5767写地址
IIC2_Test_ACK();
for(i=0;i<5;i++)
{
Write_Tea_Byte(radio_write_data[i]);
Mcu_I2C_Ack();
}
Tea_IIC_Stop();
}
//读TEA5767状态,并转换成频率
u32 radio_read(void)
{
unsigned char i;
unsigned char temp_l,temp_h;
u16 pll=0;
Tea_IIC_Start();
Write_Tea_Byte(0xc1); //读地址
IIC2_Test_ACK(); //TEA5767读地址
Tea_Init(0); //读模式
for(i=0;i<5;i++)
{
Tea_Init(0); //读模式
radio_read_data[i]=Read_Tea_Byte();
Tea_Init(1); //写模式
Mcu_I2C_Ack();
}
Tea_IIC_Stop();
temp_l=radio_read_data[1];
temp_h=radio_read_data[0];
temp_h&=0x3f;
pll=temp_h*256+temp_l;
return get_frequency(pll);
}
//由频率计算PLL
unsigned int get_pll(u32 frequency)
{
unsigned char hlsi;
unsigned int pll=0;
hlsi=radio_write_data[2]&0x10;
if (hlsi)
pll=(unsigned int)((float)((frequency+225)*4)/(float)32.768); //频率单位:k
else
pll=(unsigned int)((float)((frequency-225)*4)/(float)32.768); //频率单位:k
return pll;
}
//由PLL计算频率
u32 get_frequency(unsigned int Get_pll)
{
unsigned char hlsi;
unsigned int npll=0;
unsigned long frequency;
npll=Get_pll;
hlsi=radio_write_data[2]&0x10;
if (hlsi)
frequency=(unsigned long)((float)(npll)*(float)8.192-225); //频率单位:KHz
else
frequency=(unsigned long)((float)(npll)*(float)8.192+225); //频率单位:KHz
return frequency;
}
//手动设置频率,mode=1,+0.1MHz; mode=0:-0.1MHz ,不用考虑TEA5767用于搜台的相关位:SM,SUD
void Search_pll(unsigned int pll)
{
unsigned char i;
radio_write_data[0]=pll/256;
radio_write_data[1]=pll%256;
radio_write_data[2]=0x20;
radio_write_data[3]=0x11;
radio_write_data[4]=0x00;
Tea_IIC_Start();
Write_Tea_Byte(0xc0); //TEA5767写地址
for(i=0;i<5;i++)
{
Write_Tea_Byte(radio_write_data[i]);
Mcu_I2C_Ack();
}
Tea_IIC_Stop();
}
void Search(u32 frequency) // 调用后直接可以到frequency KHZ处
{
unsigned int pll;
pll = get_pll(frequency); // frequency ---------- pll--------- Setting
radio_write_data[0]=pll/256;
radio_write_data[1]=pll%256;
radio_write_data[2]=0x20;
radio_write_data[3]=0x11;
radio_write_data[4]=0x00;
Mute(Laud);
radio_write();
}
void Mute(char state) // 设置成静音
{
if(state==0)
radio_write_data[0]|= 128;
}
//自动搜台,mode=1,频率增加搜台; mode=0:频率减小搜台,不循环搜台
u8 auto_search(char mode)
{
u32 SearchFreq = Frequence*10;
u8 SigLevel[3];
u8 Laud_Temp = Laud;
Laud = 10;
OLED_ShowChinese(0,48,14,16,1); //搜台
OLED_ShowChinese(16,48,15,16,1);
OLED_ShowChinese(48,48,28,16,0); //停止
OLED_ShowChinese(64,48,29,16,0);
if(mode == 1){
while(SearchFreq < max_freq && KeyState[1]!=255)
{
Search(SearchFreq + AutoSearch_Step);
SigLevel[0] = TEA5767ReadRSSI();
Search(SearchFreq + 2*AutoSearch_Step);
SigLevel[1] = TEA5767ReadRSSI();
Search(SearchFreq + 3*AutoSearch_Step);
SigLevel[2] = TEA5767ReadRSSI();
OLED_ShowNum(22,25,SearchFreq/1000,3,16,1);//频率
OLED_ShowNum(55,25,(SearchFreq/10)%100,2,16,1);
OLED_ShowString(47,25,".",16,1);
OLED_ShowString(75,25,"MHZ",16,1);
OLED_Refresh();
if(SigLevel[1]>=SigLevel[2]&&SigLevel[1]>=SigLevel[0]&&SigLevel[1]>Signal_Level) //满足搜索条件
{
Frequence = (SearchFreq + 2*AutoSearch_Step)/10;
Laud = Laud_Temp;
Search(SearchFreq + 2*AutoSearch_Step);
return 1;
}
SearchFreq += AutoSearch_Step;
}
Laud = Laud_Temp;
return 0;
}
else if(mode == 0){
while(SearchFreq > min_freq && KeyState[2]!=255)
{
Search(SearchFreq - AutoSearch_Step);
SigLevel[0] = TEA5767ReadRSSI();
Search(SearchFreq - 2*AutoSearch_Step);
SigLevel[1] = TEA5767ReadRSSI();
Search(SearchFreq - 3*AutoSearch_Step);
SigLevel[2] = TEA5767ReadRSSI();
OLED_ShowNum(22,25,SearchFreq/1000,3,16,1);//频率
OLED_ShowNum(55,25,(SearchFreq/10)%100,2,16,1);
OLED_ShowString(47,25,".",16,1);
OLED_ShowString(75,25,"MHZ",16,1);
OLED_Refresh();
if(SigLevel[1]>=SigLevel[2]&&SigLevel[1]>=SigLevel[0]&&SigLevel[1]>Signal_Level) //满足搜索条件
{
Frequence = (SearchFreq - 2*AutoSearch_Step)/10;
Laud = Laud_Temp;
Search(SearchFreq - 2*AutoSearch_Step);
return 1;
}
SearchFreq -= AutoSearch_Step;
}
Laud = Laud_Temp;
}
return 0;
}
unsigned char TEA5767ReadRSSI(void) { // 读取信号强度 0 至 16 整数
radio_read();
return radio_read_data[3] >> 4;
}
主函数
#include "delay.h"
#include "sys.h"
#include "stdio.h"
#include "interrupt.h"
#include "stdlib.h"
#include "oled.h"
#include "tea5657.h"
#define StartPosition 0x08005000 //存取台在flash中的起始位置,程序大概有18KB,不能与程序冲突
u32 Frequence; //频率全局变量,单位为10KHZ
u16 count=0,result,SystemTime,Channel[41];
u8 KeyState[7],Menu1, Menu2, ItemSwitch,Menu2_1;
unsigned char countNumber = 0, SetNumber[5], Time[8], TimeBuff[8], ChannelSet=1,Signal, Laud=10;
unsigned char radio_write_data[5]={0x29,0xc2,0x40,0x12,0x40};
unsigned char radio_read_data[5]; //TEA5767读出的状态
void DrawFirst1(void); //主界面
void DrawFirst2(void); //菜单界面
void DrawFirst3(void); //手动搜台界面
void DrawFirst4(void); //存取电台
void DrawFirst5(void); //自动搜台界面
void SetPicture1_1(void); //菜单界面选择
void SetPicture2_1(void);//自动搜台
void SetPicture2_2(void);//手动搜台
void SetPicture2_3(void); //存取电台
void InputA_Init(uint16_t a); //输入配置函数
uint16_t FLASH_ReadHalfWord(uint32_t address); //到address读一个16位数据
void FLASH_WriteMoreData(uint32_t startAddress,uint16_t *writeData,uint16_t countToWrite); //address写入任意长度的16位数据
void Updata_R_Channel(void); //更新电台存储,将数组中的电台写入FLASH中
void Updata_W_Channel(void); //将Flash中的电台频率读到数组中
void fast_access(void); //快速存取
int main(void)
{
delay_init();
OLED_Init();
TIM3_INIT_Config(10); //定时10ms中断
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
Tea_Init(1); //收音机模块初始化
Updata_R_Channel(); //从Flash读取Channel数组
Frequence = Channel[24];
Search(Frequence * 10);
DrawFirst1(); //主界面
OLED_Refresh(); //更新显示
InputA_Init(GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6); //按键输入设置
Volume_Write(255); //声音打开
while(1)
{
DrawFirst1(); //画出基本界面
OLED_ShowChinese(0,48,6,16,0),//菜
OLED_ShowChinese(16,48,7,16,0);//单
// OLED_ShowNum(48,48,KeyState[3],3,16,1);//按键测试
// OLED_ShowNum(64,48,KeyState[4],3,16,1);
fast_access();
if(KeyState[1]==255)
SetPicture1_1(); //进入菜单界面
OLED_Refresh(); //更新显示
}
}
void InputA_Init(uint16_t a){ //按键初始化
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Pin = a;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOA ,&GPIO_InitStructure);
}
void Updata_R_Channel(void)
{
u8 i;
for(i=0; i<40; i++)
{
Channel[i] = FLASH_ReadHalfWord(StartPosition + 2*i);
}
}
void Updata_W_Channel(void)
{
FLASH_WriteMoreData(StartPosition,Channel,40);
}
uint16_t FLASH_ReadHalfWord(uint32_t address)
{
return *(__IO uint16_t*)address;
}
void FLASH_WriteMoreData(uint32_t startAddress,uint16_t *writeData,uint16_t countToWrite)
{
uint32_t offsetAddress=startAddress - 0X08000000; //计算去掉0X08000000后的实际偏移地址
uint32_t sectorPosition=offsetAddress/2048; //计算扇区地址
uint32_t sectorStartAddress=sectorPosition*2048+FLASH_BASE; //对应扇区的首地址
uint16_t dataIndex;
FLASH_Unlock(); //解锁写保护
FLASH_ErasePage(sectorStartAddress);//擦除这个扇区
for(dataIndex=0;dataIndex<countToWrite;dataIndex++)
{
FLASH_ProgramHalfWord(startAddress+dataIndex*2,writeData[dataIndex]);
}
FLASH_Lock();//上锁写保护
}
void DrawFirst1(void)//主界面
{
OLED_ShowChinese(16,2,0,16,1);//多功能收音机
OLED_ShowChinese(32,2,1,16,1);
OLED_ShowChinese(48,2,2,16,1);
OLED_ShowChinese(64,2,3,16,1);
OLED_ShowChinese(80,2,4,16,1);
OLED_ShowChinese(96,2,5,16,1);
OLED_ShowNum(47,22,Frequence/100,3,16,1);//频率
OLED_ShowNum(80,22,Frequence%100,2,16,1);
OLED_ShowString(72,22,".",16,1);
OLED_ShowString(100,22,"MHZ",16,1);
OLED_ShowChinese(0,48,5,16,1); //菜单
OLED_ShowChinese(16,48,6,16,1);
OLED_ShowChinese(0,22,8,16,1); //频率
OLED_ShowChinese(16,22,9,16,1);
OLED_ShowString(32,22,":",16,1);
OLED_DrawLine(0,21,130,21,1);
}
void DrawFirst2(void)//菜单界面
{
OLED_ShowChinese(0,1-ItemSwitch,10,16,1); //自动搜台
OLED_ShowChinese(16,1-ItemSwitch,11,16,1);
OLED_ShowChinese(32,1-ItemSwitch,14,16,1);
OLED_ShowChinese(48,1-ItemSwitch,15,16,1);
OLED_ShowChinese(0,16-ItemSwitch,12,16,1); //手动搜台
OLED_ShowChinese(16,16-ItemSwitch,13,16,1);
OLED_ShowChinese(32,16-ItemSwitch,14,16,1);
OLED_ShowChinese(48,16-ItemSwitch,15,16,1);
OLED_ShowChinese(0,32-ItemSwitch,16,16,1), //存取电台
OLED_ShowChinese(16,32-ItemSwitch,17,16,1),
OLED_ShowChinese(32,32-ItemSwitch,18,16,1),
OLED_ShowChinese(48,32-ItemSwitch,19,16,1);
OLED_ShowChinese(94,48,20,16,1),//返回
OLED_ShowChinese(110,48,21,16,1);
}
void DrawFirst3(void)//手动搜台界面
{
OLED_ShowChinese(32,0,22,16,1); //设置频率
OLED_ShowChinese(48,0,23,16,1);
OLED_ShowChinese(64,0,8,16,1);
OLED_ShowChinese(80,0,9,16,1);
OLED_ShowChinese(94,48,20,16,1);//返回
OLED_ShowChinese(110,48,21,16,1);
OLED_ShowChinese(0,48,24,16,1); //确认
OLED_ShowChinese(16,48,25,16,1);
OLED_ShowChinese(48,48,26,16,1); //步进
OLED_ShowChinese(64,48,27,16,1);
OLED_ShowString(48,24,".",8,1); //频率数据
OLED_ShowString(78,24,"MHZ",8,1);
OLED_ShowNum(20,24,SetNumber[0],1,8,1);
OLED_ShowNum(30,24,SetNumber[1],1,8,1);
OLED_ShowNum(40,24,SetNumber[2],1,8,1);
OLED_ShowNum(56,24,SetNumber[3],1,8,1);
OLED_ShowNum(66,24,SetNumber[4],1,8,1);
OLED_ShowNum(110,24,Signal,2,8,1); //信号强度
}
void DrawFirst4(void)//存取电台
{
OLED_ShowString(20,0,"Channel:",16,1); //频道显示
OLED_ShowNum(84,0,ChannelSet,2,16,1);
OLED_ShowNum(22,25,Channel[ChannelSet]/100,3,16,1);//频率数据
OLED_ShowNum(55,25,Channel[ChannelSet]%100,2,16,1);
OLED_ShowString(47,25,".",16,1);
OLED_ShowString(75,25,"MHZ",16,1);
OLED_ShowChinese(0,48,17,16,1); //取台
OLED_ShowChinese(16,48,19,16,1);
OLED_ShowChinese(48,48,16,16,1); //存台
OLED_ShowChinese(64,48,19,16,1);
OLED_ShowChinese(94,48,20,16,1); //返回
OLED_ShowChinese(110,48,21,16,1);
}
void DrawFirst5(void)//自动搜台界面
{
OLED_ShowChinese(48,0,8,16,1); //频率
OLED_ShowChinese(64,0,9,16,1);
OLED_ShowNum(22,25,Frequence/100,3,16,1);//频率
OLED_ShowNum(55,25,Frequence%100,2,16,1);
OLED_ShowString(47,25,".",16,1);
OLED_ShowString(75,25,"MHZ",16,1);
OLED_ShowChinese(0,48,14,16,1); //搜台
OLED_ShowChinese(16,48,15,16,1);
OLED_ShowChinese(48,48,28,16,1); //停止
OLED_ShowChinese(64,48,29,16,1);
OLED_ShowChinese(94,48,20,16,1); //返回
OLED_ShowChinese(110,48,21,16,1);
}
void SetPicture1_1(void) //菜单界面选择
{
OLED_Clear();
KeyState[1] = 0;
Menu2 = 0;
ItemSwitch = 0;
while(1){
if(KeyState[0]==255){
KeyState[0] = 0;
Menu2++;
if(Menu2 > 4) Menu2 = 0;
}
if(ItemSwitch!=Menu2/5*64) OLED_Clear();
ItemSwitch = Menu2/5*64;
DrawFirst2();
switch (Menu2){
case 1: OLED_ShowChinese(0,0-ItemSwitch,10,16,0), //自动搜台
OLED_ShowChinese(16,0-ItemSwitch,11,16,0),
OLED_ShowChinese(32,0-ItemSwitch,14,16,0),
OLED_ShowChinese(48,0-ItemSwitch,15,16,0); break;
case 2: OLED_ShowChinese(0,16-ItemSwitch,12,16,0),//手动搜台
OLED_ShowChinese(16,16-ItemSwitch,13,16,0),
OLED_ShowChinese(32,16-ItemSwitch,14,16,0),
OLED_ShowChinese(48,16-ItemSwitch,15,16,0); break;
case 3: OLED_ShowChinese(0,32-ItemSwitch,16,16,0), //存取电台
OLED_ShowChinese(16,32-ItemSwitch,17,16,0),
OLED_ShowChinese(32,32-ItemSwitch,18,16,0),
OLED_ShowChinese(48,32-ItemSwitch,19,16,0); break;
case 4: OLED_ShowChinese(94,48,20,16,0),//返回
OLED_ShowChinese(110,48,21,16,0); break;
default: break;
}
OLED_Refresh();
if(KeyState[1]==255){
delay_ms(10);
KeyState[1]=0; //消除上次按键干扰
if(Menu2==4) //返回
{
KeyState[1]=0;
OLED_Clear();
Menu1=0;
break;
}
else if(Menu2==1) //自动搜台
{
SetPicture2_1();
}
else if(Menu2==2) //手动搜台
{
SetPicture2_2();
}
else if(Menu2==3) //存取电台
{
SetPicture2_3();
}
}
}
}
void SetPicture2_1(void)//自动搜台
{
Menu2_1 = 0;
OLED_Clear();
while(1){
if(Frequence > 10800) Frequence = 8700;
if(Frequence < 8700) Frequence = 10800;
if(KeyState[0]==255){
KeyState[0] = 0;
Menu2_1++;
if(Menu2_1==3) Menu2_1=0;
}
DrawFirst5();
if(Menu2_1==1){
OLED_ShowChinese(0,48,14,16,0); //搜台
OLED_ShowChinese(16,48,15,16,0);
if(KeyState[1]==255){KeyState[1]=0;auto_search(1);}
else if(KeyState[2]==255){KeyState[2]=0;auto_search(0);}
if(!(radio_read_data[0]&0x80)) Frequence = radio_read()/10;
}
else if(Menu2_1==2){
OLED_ShowChinese(94,48,20,16,0); //返回
OLED_ShowChinese(110,48,21,16,0);
if(KeyState[1]==255){KeyState[1]=0;Menu2_1=0; OLED_Clear(); break;}
}
Channel[24] = Frequence; Search(Frequence*10); Updata_W_Channel();
OLED_Refresh();
}
}
void SetPicture2_2(void)//手动搜台
{
Menu2_1 = 0;
OLED_Clear();
while(1){
if(Frequence > 10800) Frequence = 8700;
if(Frequence < 8700) Frequence = 10800;
if(KeyState[0]==255){
KeyState[0] = 0;
Menu2_1++;
if(Menu2_1==8) Menu2_1=0;
}
Signal = TEA5767ReadRSSI();
DrawFirst3();
if(Menu2_1==0){
OLED_ShowNum(20,24,SetNumber[0],1,8,0);
if(KeyState[2]==255){KeyState[2]=0,SetNumber[0]++;if(SetNumber[0]==10) SetNumber[0]=0;}
if(KeyState[1]==255){KeyState[1]=0;if(SetNumber[0]==0) SetNumber[0]=10; SetNumber[0]--;}
}
else if(Menu2_1==1){
OLED_ShowNum(30,24,SetNumber[1],1,8,0);
if(KeyState[2]==255){KeyState[2]=0,SetNumber[1]++;if(SetNumber[1]==10) SetNumber[1]=0;}
if(KeyState[1]==255){KeyState[1]=0;if(SetNumber[1]==0) SetNumber[1]=10; SetNumber[1]--;}
}
else if(Menu2_1==2){
OLED_ShowNum(40,24,SetNumber[2],1,8,0);
if(KeyState[2]==255){KeyState[2]=0,SetNumber[2]++;if(SetNumber[2]==10) SetNumber[2]=0;}
if(KeyState[1]==255){KeyState[1]=0;if(SetNumber[2]==0) SetNumber[2]=10; SetNumber[2]--;}
}
else if(Menu2_1==3){
OLED_ShowNum(56,24,SetNumber[3],1,8,0);
if(KeyState[2]==255){KeyState[2]=0,SetNumber[3]++;if(SetNumber[3]==10) SetNumber[3]=0;}
if(KeyState[1]==255){KeyState[1]=0;if(SetNumber[3]==0) SetNumber[3]=10; SetNumber[3]--;}
}
else if(Menu2_1==4){
OLED_ShowNum(66,24,SetNumber[4],1,8,0);
if(KeyState[2]==255){KeyState[2]=0,SetNumber[4]++;if(SetNumber[4]==10) SetNumber[4]=0;}
if(KeyState[1]==255){KeyState[1]=0;if(SetNumber[4]==0) SetNumber[4]=10; SetNumber[4]--;}
}
else if(Menu2_1==5){ //手动设置台后只有按确认才能连接频率变量
OLED_ShowChinese(0,48,24,16,0);//确认
OLED_ShowChinese(16,48,25,16,0);
if(KeyState[1]==255){Frequence = 10000*SetNumber[0]+1000*SetNumber[1]+100*SetNumber[2]+10*SetNumber[3]+SetNumber[4];Search(Frequence*10);radio_read();}
}
else if(Menu2_1==6){
OLED_ShowChinese(48,48,26,16,0); //步进,与频率全局变量进行连接
OLED_ShowChinese(64,48,27,16,0);
if(KeyState[2]==255){KeyState[2]=0,Frequence+=10;Search(Frequence*10);radio_read();}
if(KeyState[1]==255){KeyState[1]=0,Frequence-=10;Search(Frequence*10);radio_read();}
SetNumber[0]=Frequence/10000,SetNumber[1]=Frequence%10000/1000,SetNumber[2]=Frequence%1000/100,SetNumber[3]=Frequence%100/10,SetNumber[4]=Frequence%10;
}
else if(Menu2_1==7){
OLED_ShowChinese(94,48,20,16,0),OLED_ShowChinese(110,48,21,16,0); //返回
if(KeyState[1]==255) {KeyState[1]=0;Menu2_1=0; OLED_Clear(); break;}
}
Channel[24] = Frequence; Search(Frequence*10); Updata_W_Channel();
OLED_Refresh();
}
}
void SetPicture2_3(void)//存取电台
{
Updata_R_Channel();
ChannelSet = 1;
OLED_Clear();
while(1){
if(KeyState[0]==255){
KeyState[0] = 0;
Menu2_1++;
if(Menu2_1==5) Menu2_1=0;
}
DrawFirst4();
if(Menu2_1==1){
OLED_ShowNum(84,0,ChannelSet,2,16,0);
if(KeyState[2]==255){KeyState[2]=0,ChannelSet++;if(ChannelSet==21) ChannelSet=1;}
if(KeyState[1]==255){KeyState[1]=0;if(ChannelSet==1) ChannelSet=21; ChannelSet--;}
}
else if(Menu2_1==2){
OLED_ShowChinese(0,48,17,16,0); //取台
OLED_ShowChinese(16,48,19,16,0);
if(KeyState[1]==255){KeyState[1]=0;Frequence = Channel[ChannelSet]; Search(Frequence*10); }
}
else if(Menu2_1==3){
OLED_ShowChinese(48,48,16,16,0); //存台
OLED_ShowChinese(64,48,19,16,0);
if(KeyState[1]==255){KeyState[1]=0;Channel[ChannelSet] = Frequence; Search(Frequence*10); Updata_W_Channel();}
}
else if(Menu2_1==4){
OLED_ShowChinese(94,48,20,16,0); //返回
OLED_ShowChinese(110,48,21,16,0);
if(KeyState[1]==255){KeyState[1]=0;Menu2_1=0; OLED_Clear(); break;}
}
OLED_Refresh();
Channel[24] = Frequence; Search(Frequence*10); Updata_W_Channel();
}
}
void fast_access(void) {
if (KeyState[3] == 255) {
if (KeyState[4] == 255) {
Channel[21] = Frequence;
Updata_W_Channel();
} else if (KeyState[5] == 255) {
Channel[22] = Frequence;
Updata_W_Channel();
} else if (KeyState[6] == 255) {
Channel[23] = Frequence;
Updata_W_Channel();
}
} else {
if (KeyState[4] == 255) {
Frequence = Channel[21];
Search(Frequence * 10);
} else if (KeyState[5] == 255) {
Frequence = Channel[22];
Search(Frequence * 10);
} else if (KeyState[6] == 255) {
Frequence = Channel[23];
Search(Frequence * 10);
}
}
}
void TIM3_IRQHandler(void) // TIM3中断函数,定时扫描按键键盘
{
KeyState[0]<<=1;
KeyState[1]<<=1;
KeyState[2]<<=1;
KeyState[3]<<=1;
KeyState[4]<<=1;
KeyState[5]<<=1;
KeyState[6]<<=1;
KeyState[0] |= GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0);
KeyState[1] |= GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1);
KeyState[2] |= GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2);
KeyState[3] |= GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3);
KeyState[4] |= GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4);
KeyState[5] |= GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5);
KeyState[6] |= GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6);
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
SystemTime++;
}
实现效果看b站视频

开源社区 


