收音机diy分享

分享作者:wechat_15135690968
作者昵称:禹黎151
评测品牌:艾矽易
评测型号:0.96寸黄蓝双色OLED模块/4P
发布时间:2025-12-31 09:21:17
1
概要
stm32F103c8t6制作收音机
开源口碑分享内容

硬件有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站视频

全部评论
暂无评论
0/144