完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
花了两个星期用TEA5767模块制作了一个FM收音机,但是只能手动搜台,自动搜台调试了几天没有调出来,不过手动搜台效果不错,能搜到十个台左右吧!自动搜台的程序不能对TEA5767模块进行读操作,哪位大神可以帮忙看看程序,谢谢啦! (附件里是手动搜索的完整程序,原理图和实物图,可以正常使用,在此分享出来)
基于MSP430单片机的fm收音机.zip
(3.11 MB, 下载次数: 258
)
下面是自动搜索部分有问题的程序,读字节的时候总是读不出来,调试时如果不将iic检测应答拉低,就不能正确应答(test一直等于1),如果拉低检测应答的data端口,能读出来字节,但也不正确。 #include unsigned char tea5767_write1[]={0x29,0x9e,0x20,0x1a,0x00}; unsigned char tea5767_read[10]; const unsigned char disp1[]={"FM收音机"}; const unsigned char disp2[]={"调频: MHZ"}; const unsigned char disp4[]={"手动搜索"}; const unsigned char disp5[]={"自动搜索"}; #define SCLK_H P2OUT|=BIT0;//tea5767的sck端口 #define SCLK_L P2OUT&=~BIT0; #define SDA_H P2OUT|=BIT1;//tea5767的data端口 #define SDA_L P2OUT&=~BIT1; #define rw_h P2OUT|=BIT3;//lcd的读写端口 #define rw_l P2OUT&=~BIT3; #define e_h P2OUT|=BIT4;//lcd的使能端口 #define e_l P2OUT&=~BIT4; unsigned long freq; unsigned int pll,key,mode; unsigned char test,read; void delay1ms(unsigned int i) { unsigned int j; while(i--) { for(j=0;j<120;j++) {} } } void delay() { unsigned int i; for(i=0;i<10;i++) {} } /******************i2c总线设置************************/ void i2c_start()//i2c开始信号,SCLK高电平期间,SDA电平由高变低 { SDA_H; delay(); SCLK_H; delay(); SDA_L; delay(); SCLK_L; delay(); } void i2c_stop()//停止信号,SCL在高电平期间,SDA出现一个上升沿 { SCLK_L; delay(); SDA_L; delay(); SCLK_H; delay(); SDA_H; delay(); } void i2c_ack()//应答信号,SCL高电平期间,SDA为低电平 { SDA_L; delay(); SCLK_H; delay(); SCLK_L; delay(); SDA_H; delay(); } void i2c_testack()//检测应答, { SCLK_L; delay(); SCLK_H; delay(); P2SEL&=~BIT1; P2DIR&=~BIT1; if(P2IN&BIT1) { test=1; } else { test=0; } delay(); P2SEL&=~BIT1; P2DIR|=BIT1; SCLK_L; delay(); } void write_byte(unsigned char data)//i2c写一个字节 { unsigned char i; for(i=0;i<8;i++) { if(data&0x80) { SDA_H; } else { SDA_L; } delay(); SCLK_H; delay(); SCLK_L; delay(); data=data<<1; } } void read_byte()//i2c读一个字节。此函数为unsigned char型 { unsigned char i; SCLK_L; delay(); read=0; P2SEL&=~BIT1; P2DIR&=~BIT1;//将p2.1口设置为输入 for(i=0;i<8;i++) { read=read<<1; SCLK_H; delay(); P2SEL&=~BIT1; P2DIR&=~BIT1;//将p2.1口设置为输入 if(P2IN&BIT1) { read=read|0x01;//或最低位 } else { read=read&0xfe;//与最低位 } delay(); SCLK_L; delay(); } P2SEL&=~BIT1; P2DIR|=BIT1; } /***********************TEA5767编程********************/ void tea5767_wr()//对TEA5767写入数据,连续写入五个字节 { unsigned char i; i2c_start(); write_byte(0xc0);//写地址 i2c_testack(); if(!test) { for(i=0;i<5;i++) { write_byte(tea5767_write1); i2c_ack(); } } i2c_stop(); } void read_tea5767()//对TEA5767进行读操作,连续读出五个字节 { unsigned char i,pll_h,pll_l; i2c_start(); write_byte(0xc1);//写地址 SDA_L; i2c_testack(); if(!test) { for(i=0;i<5;i++) { read_byte(); tea5767_read=read; i2c_ack(); } } i2c_stop(); pll_h=tea5767_read[0]; pll_l=tea5767_read[1]; pll_h=pll_h&0x3f; pll=pll_h*255+pll_l; } void get_freq()//由pll值计算频率freq { unsigned char hlsi; unsigned int npll; npll=0; npll=pll; hlsi=tea5767_write1[2]&0x10;//判断写模式下的第三个字节中的 if(hlsi) //HLSI位是高本振注入还是低本振注入 { freq=(unsigned long)((float)(npll)*(float)8.192-225);//单位KHZ } else { freq=(unsigned long)((float)(npll)*(float)8.192+225);//单位KHZ } } void get_pll()//由freq值计算pll { unsigned char hlsi; hlsi=tea5767_write1[2]&0x10;//判断写模式下的第三个字节中的 if(hlsi) //HLSI位是高本振注入还是低本振注入 { pll=(unsigned long)((float)((freq+225)*4)/(float)32.768);//单位KHZ } else { pll=(unsigned long)((float)((freq-225)*4)/(float)32.768);//单位KHZ } } void key_search()//手动搜索电台 { if(key==1)//按键加 { freq=freq+100; if(freq>108000) { freq=87500; } } if(key==2)//按键减 { freq=freq-100; if(freq<87500) { freq=108000; } } get_pll();//由加或减后的freq计算pll tea5767_write1[0]=pll/256; tea5767_write1[0]&=0x3f; tea5767_write1[1]=pll%256; tea5767_write1[2]=0x20; tea5767_write1[3]=0x1a; tea5767_write1[4]=0x00; tea5767_wr();//写入TEA5767 } void auto_search()//自动搜索 { if(key==1)//按键加台 { read_tea5767(); get_freq(); while(freq<=108000) { get_pll(); tea5767_write1[0]=pll/256; tea5767_write1[0]|=0x40;//在搜索模式 tea5767_write1[1]=pll%256; tea5767_write1[2]=0xa0; tea5767_write1[3]=0x1a; tea5767_write1[4]=0x00; tea5767_wr(); delay1ms(1); read_tea5767(); if(tea5767_read[0]&0x80) { return; } get_freq(); if(tea5767_read[0]&0x40) { freq=87500; } } freq=87500; } if(key==2)//按键减台 { read_tea5767(); get_freq(); while(freq>=87500) { get_pll(); tea5767_write1[0]=pll/256; tea5767_write1[0]|=0x40;//在搜索模式 tea5767_write1[1]=pll%256; tea5767_write1[2]=0x20; tea5767_write1[3]=0x1a; tea5767_write1[4]=0x00; tea5767_wr(); delay1ms(10); read_tea5767(); if(tea5767_read[0]&0x80) { return; } get_freq(); if(tea5767_read[0]&0x40) { freq=108000; } } freq=108000; } } /*************************按键中断*****************/ #pragma vector=PORT1_VECTOR //P1口按键中断 __interrupt void port1(void) { if(P1IFG&0X04)//P1.2选择手动搜索模式还是自动搜索 { mode^=1; } if(P1IFG&0X01)//P1.0按键加 { key=1; if(mode==1) { auto_search(); } else { key_search(); } } if(P1IFG&0X02)//P1.1按键减 { key=2; if(mode==1) { auto_search(); } else { key_search(); } } P1IFG=0X00; delay1ms(10);//延时消抖 } /*******************LCD12864显示*********************/ void sendbyte(unsigned int data)//向LCD发送一个字节 { unsigned char i; for(i=0;i<8;i++) { if(data&0x80) { rw_h; } else { rw_l; } e_l; e_h; data=data<<1; } } void write_com(unsigned int comm)//写指令 { sendbyte(0xf8); sendbyte(comm&0xf0); sendbyte((comm<<4)&0xf0); //delay1ms(1); } void write_data(unsigned char data0)//写数据 { sendbyte(0xfa); sendbyte(data0&0xf0); sendbyte((data0<<4)&0xf0); //delay1ms(1); } void lcd_init()//LCD初始化 { write_com(0x30); write_com(0x0c); write_com(0x01); write_com(0x06); } void display()//液晶显示(不变的内容) { unsigned char i; i=0; write_com(0x81); while(disp1!=' |