MSP430(f149)學(xué)習(xí)筆記——紅外遙控發(fā)射
紅外發(fā)送原理
紅外發(fā)送實際上是按照一定的時間間隔,斷斷續(xù)續(xù)的發(fā)送紅外射線來進行數(shù)據(jù)傳輸,為了提高數(shù)據(jù)傳輸?shù)臏?zhǔn)確定和降低功耗,紅外一般是采用38K的紅外調(diào)制信號,其中,38K允許上下浮動1K以內(nèi)的誤差。紅外發(fā)送的開頭需要一個引導(dǎo)位,引導(dǎo)位是發(fā)送9ms,然后停止4.5ms,如果發(fā)送完一個數(shù)據(jù)之后還需要再發(fā)數(shù)據(jù)的話還需要連發(fā)碼,連發(fā)碼是先發(fā)送9ms,然后停止4.5ms。引導(dǎo)碼和連發(fā)碼的波形如下:
本文引用地址:http://m.butianyuan.cn/article/201611/322815.htm引導(dǎo)碼和連發(fā)碼之后是32位數(shù)據(jù)位,這32位數(shù)據(jù)位實際上是一個字節(jié),其中,前16位是用戶自定義地址碼,用來區(qū)分紅外是發(fā)給誰的,比如,電視的紅外遙控是不能操作冰箱或空調(diào)的,剩下的16位是傳輸?shù)臄?shù)據(jù),其中前8位是要傳送的一個字節(jié),后8位是這個字節(jié)的反碼,用來校驗數(shù)據(jù)傳輸?shù)氖欠裾_的,數(shù)據(jù)位無非就是0或1,其中0是先發(fā)送560us紅外,然后停止565us,1是先發(fā)送560us然后停止1685us,0和1的波形如下:
每次傳輸實際上就是一個引導(dǎo)碼加32位數(shù)據(jù)位或者一個連發(fā)碼加32位數(shù)據(jù)位,整體的波形如下:
注意,你上所有的波形都是接收時的波形,由于紅外接收頭,如HS0038B,在采集到38K紅外線時輸出低電平,在采集不到38K紅外線時輸出高電平,所以,當(dāng)發(fā)送紅外線時在波形中為低電平,停止發(fā)送時反而為高電平。
實現(xiàn)電路
熟習(xí)了原理以后,再來設(shè)計電路圖就非常簡單了,用兩個三極管停止串聯(lián),其中一個的基極(無論是PNP還是NPN,都是旁邊那個腳)接到38K方波上,另一個的基極接到發(fā)送控制引腳上,我這里沒有自己來繪制原理圖,采用了一個網(wǎng)上的原理圖,具體如下:
代碼設(shè)計
下面的原理部分都理通了,下面,我們用MSP430來實現(xiàn)設(shè)計,其中P2.3口是MSP430的PWM輸出引腳,這里是輸出38K方波,P2.2口為發(fā)送停止控制引腳。具體代碼如下:
- #include<msp430x14x.h>
- staticunsignedintcnt=0;
- voiddelay_ms(unsignedintms){
- cnt=ms;
- TBCCR0=1000;
- TBCTL=CNTL_0+TASSEL_2+MC_1+ID_3;
- TBCCTL0=CCIE;
- while(cnt!=0);
- TBCTL=MC_0;
- }
- voiddelay_us(unsignedintus){
- cnt=1;
- TBCCR0=us;
- TBCTL=CNTL_0+TASSEL_2+MC_1+ID_3;
- TBCCTL0=CCIE;
- while(cnt!=0);
- TBCTL=MC_0;
- }
- voidir_open(){
- P2DIR|=BIT2|BIT3;//P2.2,P2.3輸出
- P2SEL|=BIT3;//P2.2:IOP2.3:TA0
- P2OUT&=~(BIT2|BIT3);
- //38K->P2.3
- CCR0=(int)(26.3*8+0.5);
- CCTL1=OUTMOD_6;
- CCR1=(int)(13.15*8+0.5);
- TACTL=TASSEL_2+MC_1;
- }
- voidir_start(){
- P2OUT|=BIT2;
- delay_us(9000);
- P2OUT&=~BIT2;
- delay_us(4500);
- }
- voidir_next(){
- P2OUT|=BIT2;
- delay_us(9000);
- P2OUT&=~BIT2;
- delay_us(2250);
- }
- voidir_send_byte(unsignedcharc){
- unsignedchari;
- for(i=0;i!=8;++i){
- P2OUT|=BIT2;
- delay_us(560);
- P2OUT&=~BIT2;
- if(c&0x01){
- delay_us(1685);
- }
- else{
- delay_us(565);
- }
- c>>=1;
- }
- }
- voidir_end(){
- P2OUT|=BIT2;
- delay_us(300);
- P2OUT&=~BIT2;
- }
- voidir_put(unsignedcharc){
- ir_start();
- ir_send_byte(0x00);
- ir_send_byte(0xff);
- ir_send_byte(c);
- ir_send_byte(~c);
- ir_end();
- }
- voidir_close(){
- P2SEL&-~BIT3;
- P2DIR|=BIT3;
- P2OUT&=~BIT3;
- TACTL=TACLR;
- }
- voidmain(void)
- {
- WDTCTL=WDTPW+WDTHOLD;//StopWDT
- BCSCTL1&=~XT2OFF;//使能XT2
- do
- {
- IFG1&=~OFIFG;//清除XT2標(biāo)志
- _NOP();
- }
- while((IFG1&OFIFG));//等待外部晶振穩(wěn)定即寄存器IFGI的OFIFG位等于0
- BCSCTL2|=SELM_2;//將MCLK配置為XT2
- BCSCTL2|=SELS;//將SMCLK配置1/2XT2即4M
- _EINT();
- ir_open();
- //ir_close();//關(guān)閉紅外函數(shù),這里不用
- while(1){
- delay_ms(1000);
- //P2OUT^=BIT2;
- ir_put(0x83);
- }
- }
- #pragmavector=TIMERB0_VECTOR
- __interruptvoidtimerb_handler(){
- --cnt;
- }
好了,看過上面這些資料,紅外的發(fā)送就不會有什么疑問了,調(diào)試的時候我是用51單片機的紅外解碼測試程序來調(diào)試的,現(xiàn)在已經(jīng)完全沒有問題了,如果有什么疑問,歡迎留言討論。
評論