|
手上有個(gè)收音機(jī)模塊,借鑒51單片機(jī)例程,自己430寫(xiě)了個(gè)小程序。用數(shù)碼管顯示。
剛寫(xiě)好了,又被刷沒(méi)有了,我哭了,還得再寫(xiě),這太啃了吧。
言歸正傳,這個(gè)小實(shí)驗(yàn)也是我無(wú)意中想的,手中有430的片子,又想自己做個(gè)小東西,只要能個(gè)簡(jiǎn)單的電子收音機(jī),程序代碼都是借鑒的,所以這個(gè)只是玩玩而已,以供參考。
//iic.h 這個(gè)是收音機(jī)的驅(qū)動(dòng)程序,我是借鑒新浪一位網(wǎng)友c51程序?qū)懙茫蠹宜严戮椭懒恕?br />
#include"config.h"
uchar fm_write[5]={0x00,0x00,0x31,0x17,0x00};
uchar fm_read[5]={0,0,0,0,0};
uint freq,PLL,frequency;
uchar count;
uchar mode,hisi;
//msp430內(nèi)部PLL時(shí)鐘12M,最大可以達(dá)到16M.
void extern_16m()
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
if (CALBC1_12MHZ==0xFF) // If calibration constant erased
{
while(1); // do not load, trap CPU!!
}
DCOCTL = 0; // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_12MHZ;
DCOCTL = CALDCO_12MHZ; // Load 8MHz constants
frequency=10585;
}
void iic_start()
{
SDA_DIR_OUT;
SCL_DIR_OUT;
SDA1; //發(fā)送起始條件的數(shù)據(jù)信號(hào)
delay_us(1);
SCL1;
delay_us(5); //起始條件建立時(shí)間大于4.7us,延時(shí)
SDA0; //發(fā)送起始信號(hào)
delay_us(5); // 起始條件鎖定時(shí)間大于4μs
SCL0; //鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù)
// delay_us(2);
}
void iic_stop()//總線結(jié)束
{
SDA_DIR_OUT;
SCL_DIR_OUT;
SDA0; //發(fā)送結(jié)束條件的數(shù)據(jù)信號(hào)
delay_us(1); //發(fā)送結(jié)束條件的時(shí)鐘信號(hào)
SCL1; //結(jié)束條件建立時(shí)間大于4us
delay_us(5);
SDA1; //發(fā)送I2C總線結(jié)束信號(hào)
delay_us(1);
}
void write_8bit(uchar c)
{
uchar BitCnt;
SDA_DIR_OUT;
SCL_DIR_OUT;
for(BitCnt=0;BitCnt<8;BitCnt++) //要傳送的數(shù)據(jù)長(zhǎng)度為8位
{
if(c&0x80)
SDA1; //判斷發(fā)送位
else
SDA0;
delay_us(1);
SCL1;
delay_us(5);
c=c<<1;
SCL0; //置時(shí)鐘線為高,通知被控器開(kāi)始接收數(shù)據(jù)位
delay_us(1);
}
}
uchar read_8bit()//讀取8bit數(shù)據(jù)
{
SCL_DIR_OUT;
SDA_DIR_IN;
uchar i,dat=0;
for(i=0;i<8;i++)
{ SCL1;
dat<<=1;
if(SDA_IN==0x40)
dat|=0x01;
delay_us(5);
SCL0;
}
return(dat);
}
void send_ack()//發(fā)送認(rèn)可位,用于讀取數(shù)據(jù)的認(rèn)可
{ SDA_DIR_OUT;
SCL_DIR_OUT;
SDA0;
delay_us(1);
SCL1;
delay_us(5);
SCL0;
}
void send_noack()
{
SDA_DIR_OUT;
SCL_DIR_OUT;
SDA1;
delay_us(1);
SCL1;
delay_us(5);
SDA0;
SCL0;
}
uchar check_ack()//檢測(cè)確認(rèn)位,如果返回值是0表示數(shù)據(jù)傳輸成功
{ uchar ack_bit;
SDA_DIR_OUT;
SCL_DIR_OUT;
SDA1;
delay_us(1);
SCL1;
delay_us(5);
SDA_DIR_IN;
ack_bit=SDA_IN;
SCL0;
return(ack_bit);
}
void get_frequency()
{ ulong y;
y=PLL;
hisi=fm_write[2]&0x10;
if(hisi)
freq=(y*8192+225000)/10000;
else
freq=(y*8192-225000)/10000 ;
}
void get_pll()
{ ulong freq1,y=frequency;
freq1=y*10000;
hisi=fm_write[2]&0x10;
if(hisi)
PLL=((freq1+225000)*4)/32768;
else
PLL=((freq1-225000)*4)/32768;
}
void read_5byte()
{uchar i,tempH,tempL;
iic_start();
write_8bit(read_order);
check_ack();
for(i=0;i<5;i++)
{fm_read[i]=read_8bit();
send_ack();
}
send_noack();
iic_stop();
tempH=fm_read[0];
tempL=fm_read[1];
tempH&=0x3f;
PLL=tempH*256+tempL;
get_frequency();
}
void write_5byte()
{uchar i;
iic_start();
write_8bit(write_order);
check_ack();
for(i=0;i<5;i++)
{write_8bit(fm_write[i]);
check_ack();
}
iic_stop();
}
void refurbish_5767()//FM收音芯片數(shù)據(jù)刷新一次
{
get_pll();//計(jì)算PLL,
fm_write[0]=PLL/256;
fm_write[1]=PLL%256;
fm_write[2]=0x31;
fm_write[3]=0x11;
fm_write[4]=0x00;
if(mode)fm_write[2]|=0x80;//給SUD=1,向上搜索模式
else fm_write[2]&=0x7f;//給SUD=0,向下搜索模式
write_5byte();
read_5byte();
}
//config.h
#include "io430.h"
#define CPU_F ((double)12000000) //外部高頻晶振8MHZ
//#define CPU_F ((double)32768) //外部低頻晶振32.768KHZ
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define SDA_DIR_OUT P1DIR|=BIT6
#define SDA_DIR_IN P1DIR&=~BIT6
#define SCL_DIR_OUT P1DIR|=BIT7
#define SDA_IN P1IN&BIT6
#define SDA1 P1OUT|=BIT6
#define SDA0 P1OUT&=~BIT6
#define SCL1 P1OUT|=BIT7
#define SCL0 P1OUT&=~BIT7
#define max_freq 12800
#define min_freq 7600
#define write_order 0xc0
#define read_order 0xc1
#define keycode P1IN&0x03
//key.h
#include "io430.h"
uchar key_value;
uchar key_code;
void key_init()
{
P1IE |= BIT0+BIT1+BIT2; // P1.0-P1.2 IO口中斷使能
P1IES |= 0x07; // P1.0-P1.2 IO口邊沿觸發(fā)中斷方式設(shè)置
P1IFG &= ~(BIT0+BIT1+BIT2); // P1.0-P1.2 IO口中斷標(biāo)志位清除
}
//外部中斷查詢方式,如果有中斷就運(yùn)行程序
void key_set()
{
if(key_value!=0)
{
switch(key_value)
{
case 0x01:
switch(mode)
{
case 0:mode=1;break;
case 1:mode=0;break;
default:mode=0;break;
}
break;
case 0x02:
switch(mode)
{
case 0:++frequency;break;
case 1:--frequency;break;
default:break;
}
break;
case 0x03:
switch(mode)
{
case 0:frequency+=10;break;
case 1:frequency-=10;break;
default:break;
}
break;
default:break;
}
if(frequency>max_freq)
frequency=min_freq;
if(frequency frequency=max_freq;
key_code=3*mode+key_value;
key_value=0;
}
}
//外部中斷判斷按鍵
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
switch (P1IFG&0x07)
{
case 0x01: key_value=0x01;
break;
case 0x02: key_value=0x02;
break;
case 0x04: key_value=0x03;
break;
default: P1IFG = 0; key_value=0; // P2.0-P2.2 IO口中斷標(biāo)志位清除
break;
}
P1IFG = 0; // P2.0-P2.2 IO口中斷標(biāo)志位清除
}
//ta.h
#include"config.h"
uint t;
uchar set_hex;
extern void display();
void init_TA()
{
TACCTL0 = CCIE; // TACCR0 interrupt enabled
TACCR0 = 60000; //5ms中斷一次
TACTL = TASSEL_2 + MC_1; // SMCLK, upmode
}
//顯示在數(shù)碼管上,我用的是cd4511,占用6的io口顯示數(shù)碼管,p2.0-p2.1位選,p2.2-p2.5段選。
void display()
{
P1OUT|=BIT3;
P2OUT=0X00;
switch(set_hex)
{
case 0:set_hex=1;P2OUT|=BIT0;P2OUT|=key_code<<2;break;
case 1:set_hex=0;P2OUT|=BIT1;P2OUT|=mode<<2;break;
default:break;
}
P1OUT&=-BIT3;
}
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
display();
if(++t==50)
{
t=0; //每250ms刷新數(shù)據(jù)
refurbish_5767();//FM收音芯片數(shù)據(jù)刷新一次
}
}
//main.c
#include"iic.h"
#include"key.h"
#include"config.h"
#include"ta.h"
#include"shumaguan.h"
int main( void )
{
extern_16m();
key_init();
init_TA();
shumaguan_init();
__bis_SR_register(GIE);
while(1)
{
key_set();
}
}
//iic.h
#include"config.h"
uchar fm_write[5]={0x00,0x00,0x31,0x17,0x00};
uchar fm_read[5]={0,0,0,0,0};
uint freq,PLL,frequency;
uchar count;
uchar mode,hisi;
void extern_16m()
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
if (CALBC1_12MHZ==0xFF) // If calibration constant erased
{
while(1); // do not load, trap CPU!!
}
DCOCTL = 0; // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_12MHZ;
DCOCTL = CALDCO_12MHZ; // Load 8MHz constants
frequency=10585;
}
void iic_start()
{
SDA_DIR_OUT;
SCL_DIR_OUT;
SDA1; //發(fā)送起始條件的數(shù)據(jù)信號(hào)
delay_us(1);
SCL1;
delay_us(5); //起始條件建立時(shí)間大于4.7us,延時(shí)
SDA0; //發(fā)送起始信號(hào)
delay_us(5); // 起始條件鎖定時(shí)間大于4μs
SCL0; //鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù)
// delay_us(2);
}
void iic_stop()//總線結(jié)束
{
SDA_DIR_OUT;
SCL_DIR_OUT;
SDA0; //發(fā)送結(jié)束條件的數(shù)據(jù)信號(hào)
delay_us(1); //發(fā)送結(jié)束條件的時(shí)鐘信號(hào)
SCL1; //結(jié)束條件建立時(shí)間大于4us
delay_us(5);
SDA1; //發(fā)送I2C總線結(jié)束信號(hào)
delay_us(1);
}
void write_8bit(uchar c)
{
uchar BitCnt;
SDA_DIR_OUT;
SCL_DIR_OUT;
for(BitCnt=0;BitCnt<8;BitCnt++) //要傳送的數(shù)據(jù)長(zhǎng)度為8位
{
if(c&0x80)
SDA1; //判斷發(fā)送位
else
SDA0;
delay_us(1);
SCL1;
delay_us(5);
c=c<<1;
SCL0; //置時(shí)鐘線為高,通知被控器開(kāi)始接收數(shù)據(jù)位
delay_us(1);
}
}
uchar read_8bit()//讀取8bit數(shù)據(jù)
{
SCL_DIR_OUT;
SDA_DIR_IN;
uchar i,dat=0;
for(i=0;i<8;i++)
{ SCL1;
dat<<=1;
if(SDA_IN==0x40)
dat|=0x01;
delay_us(5);
SCL0;
}
return(dat);
}
void send_ack()//發(fā)送認(rèn)可位,用于讀取數(shù)據(jù)的認(rèn)可
{ SDA_DIR_OUT;
SCL_DIR_OUT;
SDA0;
delay_us(1);
SCL1;
delay_us(5);
SCL0;
}
void send_noack()
{
SDA_DIR_OUT;
SCL_DIR_OUT;
SDA1;
delay_us(1);
SCL1;
delay_us(5);
SDA0;
SCL0;
}
uchar check_ack()//檢測(cè)確認(rèn)位,如果返回值是0表示數(shù)據(jù)傳輸成功
{ uchar ack_bit;
SDA_DIR_OUT;
SCL_DIR_OUT;
SDA1;
delay_us(1);
SCL1;
delay_us(5);
SDA_DIR_IN;
ack_bit=SDA_IN;
SCL0;
return(ack_bit);
}
void get_frequency()
{ ulong y;
y=PLL;
hisi=fm_write[2]&0x10;
if(hisi)
freq=(y*8192+225000)/10000;
else
freq=(y*8192-225000)/10000 ;
}
void get_pll()
{ ulong freq1,y=frequency;
freq1=y*10000;
hisi=fm_write[2]&0x10;
if(hisi)
PLL=((freq1+225000)*4)/32768;
else
PLL=((freq1-225000)*4)/32768;
}
void read_5byte()
{uchar i,tempH,tempL;
iic_start();
write_8bit(read_order);
check_ack();
for(i=0;i<5;i++)
{fm_read[i]=read_8bit();
send_ack();
}
send_noack();
iic_stop();
tempH=fm_read[0];
tempL=fm_read[1];
tempH&=0x3f;
PLL=tempH*256+tempL;
get_frequency();
}
void write_5byte()
{uchar i;
iic_start();
write_8bit(write_order);
check_ack();
for(i=0;i<5;i++)
{write_8bit(fm_write[i]);
check_ack();
}
iic_stop();
}
void refurbish_5767()//FM收音芯片數(shù)據(jù)刷新一次
{
get_pll();//計(jì)算PLL,
fm_write[0]=PLL/256;
fm_write[1]=PLL%256;
fm_write[2]=0x31;
fm_write[3]=0x11;
fm_write[4]=0x00;
if(mode)fm_write[2]|=0x80;//給SUD=1,向上搜索模式
else fm_write[2]&=0x7f;//給SUD=0,向下搜索模式
write_5byte();
read_5byte();
}
//config.h
#include "io430.h"
#define CPU_F ((double)12000000) //外部高頻晶振8MHZ
//#define CPU_F ((double)32768) //外部低頻晶振32.768KHZ
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define SDA_DIR_OUT P1DIR|=BIT6
#define SDA_DIR_IN P1DIR&=~BIT6
#define SCL_DIR_OUT P1DIR|=BIT7
#define SDA_IN P1IN&BIT6
#define SDA1 P1OUT|=BIT6
#define SDA0 P1OUT&=~BIT6
#define SCL1 P1OUT|=BIT7
#define SCL0 P1OUT&=~BIT7
#define max_freq 12800
#define min_freq 7600
#define write_order 0xc0
#define read_order 0xc1
#define keycode P1IN&0x03
//key.h
#include "io430.h"
uchar key_value;
uchar key_code;
void key_init()
{
P1IE |= BIT0+BIT1+BIT2; // P2.0-P2.2 IO口中斷使能
P1IES |= 0x07; // P2.0-P2.2 IO口邊沿觸發(fā)中斷方式設(shè)置
P1IFG &= ~(BIT0+BIT1+BIT2); // P2.0-P2.2 IO口中斷標(biāo)志位清除
}
void key_set()
{
if(key_value!=0)
{
switch(key_value)
{
case 0x01:
switch(mode)
{
case 0:mode=1;break;
case 1:mode=0;break;
default:mode=0;break;
}
break;
case 0x02:
switch(mode)
{
case 0:++frequency;break;
case 1:--frequency;break;
default:break;
}
break;
case 0x03:
switch(mode)
{
case 0:frequency+=10;break;
case 1:frequency-=10;break;
default:break;
}
break;
default:break;
}
if(frequency>max_freq)
frequency=min_freq;
if(frequency<min_freq)
frequency=max_freq;
key_code=3*mode+key_value;
key_value=0;
}
}
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
switch (P1IFG&0x07)
{
case 0x01: key_value=0x01;
break;
case 0x02: key_value=0x02;
break;
case 0x04: key_value=0x03;
break;
default: P1IFG = 0; key_value=0; // P2.0-P2.2 IO口中斷標(biāo)志位清除
break;
}
P1IFG = 0; // P2.0-P2.2 IO口中斷標(biāo)志位清除
}
//ta.h
#include"config.h"
uint t;
uchar set_hex;
extern void display();
void init_TA()
{
TACCTL0 = CCIE; // TACCR0 interrupt enabled
TACCR0 = 60000; //5ms中斷一次
TACTL = TASSEL_2 + MC_1; // SMCLK, upmode
}
void display()
{
P1OUT|=BIT3;
P2OUT=0X00;
switch(set_hex)
{
case 0:set_hex=1;P2OUT|=BIT0;P2OUT|=key_code<<2;break;
case 1:set_hex=0;P2OUT|=BIT1;P2OUT|=mode<<2;break;
default:break;
}
P1OUT&=-BIT3;
}
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
display();
if(++t==50)
{
t=0;
refurbish_5767();//FM收音芯片數(shù)據(jù)刷新一次
}
}
//main.c
#include"iic.h"
#include"key.h"
#include"config.h"
#include"ta.h"
#include"shumaguan.h"
int main( void )
{
extern_16m();
key_init();
init_TA();
shumaguan_init();
__bis_SR_register(GIE);
while(1)
{
key_set();
}
}
|
-
-
收音機(jī).zip
2016-3-30 19:47 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
203.25 KB, 下載次數(shù): 144, 下載積分: 黑幣 -5
|