picマイコンの使い方

PICマイコンの8bitマイコンから32bitマイコンまで使いこなすぞ! 周辺機能やアセンブラ、C言語を使いこなすぞ。ARMには負けないぞ! 頼みの綱はPIC32MZだ!たのしみだなー

UART

【dsPIC33FJ128MC802】UARTを使ってみる。送受信


◆dsPIC33FJ128MC802でUARTを使ってみます。



1)参考
PIC32MXで作ったプログラムを移植します。普通順序的には逆ですね。
リファレンスマニュアル:DS70188Dが参考になります。

2)イニシャライズと設定
・送信仕様:1秒毎に1byteのキャラクター’a’を送信させます。
・受信仕様:4byte受信したら割り込んで最初の1byteをエコーバックさせます。

1.ボーレートの設定
70188Dのpage10の式通りに・・・
ボーレート:9600bpsの場合(低速モードBRGH=0)
U1BRG = (Fcy/(16×ボーレート)-1)
  = (39.61MHz/16×9600)-1
  = 257

2.ポートの割り当て
 ①RB15を受信割り当て
 「RPINR18bits.U1RXR = 15;」
 「TRISBbits.TRISB15 = 1;」←入力設定を忘れずに!
 ②RB14を送信割り当て
 「RPOR7bits.RP14R = 3;」

3.前処理:割り込み設定
 ①「IEC0bits.U1RXIE = 1;」受信割り込み
 ②「IPC2bits.U1RXIP = 6;」優先レベル6(適当です。)

送信の処理・・・
①ステータスの送信バッファをチェック
 while(U1STAbits.UTXBF);
②送信レジスターU1TXREGにデータを入れる。
 U1TXREG = 'a';

受信の処理・・・
割り込み時点でバッファーに文字が入ってますので取り出してください。
①ステータスの受信バッファをチェック
 while(!U1STAbits.URXDA);
②受信レジスターを読む。for文使って4byte退避します。
 rev_data[i] = U1RXREG;

3)ソース

//=========================================================
// TEST
//=========================================================
//== ヘッダファイル ============================================
#include <p33fj128mc802.h>
#include <stdio.h>

//== define ===========================================================
#define SB1602_RE LATBbits.LATB7
#define debug_pin LATBbits.LATB6
//== configuration ======================================================
_FBS(BSS_NO_FLASH //No Boot program Flash segment
& BWRP_WRPROTECT_OFF); //Boot Segment may be written
_FGS(GSS_OFF //User program memory is not code-protected
& GWRP_OFF); //User program memory is not write-protected
_FOSCSEL(FNOSC_FRCPLL //Internal Fast RC (FRC) w/ PLL
& IESO_OFF); //Start-up device with user-selected oscillator source
_FOSC(FCKSM_CSDCMD //Both Clock Switching and Fail-Safe Clock Monitor are disabled
& IOL1WAY_ON // Allow Only One Re-configuration
& OSCIOFNC_ON //OSC2 pin has digital I/O function
& POSCMD_NONE); //Primary Oscillator Disabled
_FWDT(FWDTEN_OFF); //Watchdog timer enabled/disabled by user software
_FPOR(FPWRT_PWR128 //PowerOnReset_128ms
& ALTI2C_OFF); //I2C mapped to SDA1/SCL1 pins
_FICD(JTAGEN_OFF //JTAG is Disabled
& ICS_PGD1); //Communicate on PGC1/EMUC1 and PGD1/EMUD1
//== interrupt_function_prototype ================================================
void __attribute__((interrupt,no_auto_psv)) _U1RXInterrupt(void); //UART_RX_Interrupt
//== uart ========================================================================
char U1RXstring(void); //receive_string
void U1TXstring(char *string, unsigned char count); //tex_string
//== Sb1602_LCD用プロトタイプ =========================================================
void sb1602_init(void); //sb1602初期化
void sb1602_cmd_write(unsigned char data); //sb1602コマンド書き込み
void sb1602_data_write(unsigned char data); //sb1602データ書き込み
//== sb1602文字列書き込み(配列 + 行目 + 出力数) =======================================
void sb1602_string_write(char *data, char line, unsigned char count);

//== MyTimer =====================================================================
void delay_us(unsigned int usec); //Timer1を利用したusec関数
void delay_ms(unsigned int msec); //msec関数
//== StringBox ===================================================================
unsigned char sute_byte[70];
unsigned char bmp_byte[200];
char rev_data[4]; //uart_rex
char string_box[16] = "neko()";
unsigned int adc_tex0[16];
unsigned int adc_tex1[16];
//== main ==================================================================
int main(void)
{
//== クロックの設定 ======================================================
//== Fcy=Fosc/2=7.37M*((PLLFBD+2)/(N2*N1))/2=39.61MHz ================
PLLFBDbits.PLLDIV = 41; //M=PLLFBD+2
CLKDIVbits.PLLPOST = 0; //N2=2
CLKDIVbits.PLLPRE = 0; //N1=2
OSCTUN = 0; //TuneFRC:7.37MHz
RCONbits.SWDTEN = 0; //Disable Watch Dog
while(OSCCONbits.LOCK != 1); //wait for PLL Lock
//== AD切り替え ==========================================================
AD1PCFGL = 0xffff; //全digital
//=== TRISA ===========================================================
TRISA = 0x0000; //initial_
//== TRISB =============================================================
TRISB = 0x0000; //input:
//== i2c設定 ============================================================
//== TIMER1設定 =========================================================
T1CONbits.TON = 0; //15_Timer1_OFF
T1CONbits.TSIDL = 1; //13_アイドルモード:Sleep中は停止
T1CONbits.TGATE = 0; //6_ゲート積算時間:OFF
T1CONbits.TCKPS = 0B00; //5-4_PS1:1
T1CONbits.TCS = 0; //2_クロックソース:内部
IEC0bits.T1IE = 0; //割り込み拒否
IPC0bits.T1IP = 0; //優先レベル0
//== UART1設定 =========================================================
//Port_set
RPINR18bits.U1RXR = 15; //RP15_U1RX
TRISBbits.TRISB15 = 1; //U1RX_input
RPOR7bits.RP14R = 3; //U1TX_RP14
U1MODE = 0x0000; //初期クリア
U1MODEbits.UARTEN = 1; //15_UART有効
U1MODEbits.RTSMD = 1; //11_単方向モード
U1MODEbits.BRGH = 0; //3_低速
U1STA = 0x0000; //初期クリア
U1STAbits.URXISEL = 0B11; //4ByteReceive_Interrupt
U1STAbits.UTXEN = 1; //10_TX_enable
U1BRG = 257; //低速,ビットレート:9600bps U1BRG=(Fcy/(16*9600))-1
//== ADC_10 ================================================================
//== 前処理 ======================================================
IEC0bits.U1RXIE = 1; //UART受信割り込み許可
IPC2bits.U1RXIP = 6; //優先レベル1
//== while文 ===========================================================
while(1)
{
while(U1STAbits.UTXBF);
U1TXREG = 'a'; //デバック
delay_ms(1000);
//LATAbits.LATA3 = !LATAbits.LATA3;
}//while(1)
}//int main(void)


//== delay_us関数 =================================================================
void delay_us(unsigned int usec)
{
TMR1 = 0; //TMR1=0
T1CONbits.TON = 1; //Timer1_start
PR1 = 39; //PR1値:((目的値1usec)/(1サイクル:0.0025usec*PS)-1)=39
unsigned int i;
for(i=0; i<usec; i++)
{ //タイマーフラグ待ち
while(!IFS0bits.T1IF); //Timer1割り込みフラグチェック(IFS0bits.T1IF==0)
IFS0bits.T1IF = 0; //割り込みフラグ下ろす
}//for(i=0; i<usec; i++)
}//void delay_usec();
//== delay_ms関数 ==================================================================
void delay_ms(unsigned int msec)
{
unsigned int i;
for(i=0; i<msec; i++)
{
delay_us(1000); //call:1000usec
}//for
}//void delay_ms
//== U1RXInterrupt =========================================================
void __attribute__((interrupt,no_auto_psv)) _U1RXInterrupt(void)
{
IFS0bits.U1RXIF = 0; //Interrup_Flag_Clear
//== Framing&OverRun Error Check=================================
if(U1STAbits.OERR || U1STAbits.FERR) //OERR_or_FERR
{
U1STA &= 0xFFF0; //??PERR_FERR_OERR_URXDA????
//UART1_RESET
U1MODEbits.UARTEN = 0; //UART1_Disable
U1MODEbits.UARTEN = 1; //UART1_Enable
}//if(U1STAbits.OERR || U1STAbits.FERR)
//== UART_REV ==============================================================
//*rev_data = U1RXstring(); //UARTReceiveFunction
U1RXstring(); //UARTReceiveFunction
//== DebugFlag =============================================================
while(U1STAbits.UTXBF); //Buffer_empty
U1TXREG = rev_data[0];
debug_pin = !debug_pin;
}//void __attribute__((interrupt,no_auto_psv)) _U1RXInterrupt(void)
//== U1RXstringGet =============================================================
char U1RXstring(void)
{
unsigned char i;
for(i=0; i<4; i++) //4byteInterrupt
{
while(!U1STAbits.URXDA); //Buffer_has_data
rev_data[i] = U1RXREG; //SET_Buffer
}//for(i=0; i<count; i++)
return(*rev_data);
}//void U1string(unsigned char *tex, char count)
//== U1TXstring ==============================================================
void U1TXstring(char *string, unsigned char count)
{
unsigned char i;
for(i=0; i<count; i++)
{
while(U1STAbits.UTXBF); //Buffer_empty
U1TXREG = string[i]; //set_Buffer
}//for(i=0; i<count; i++)
}//void U1string(unsigned char *tex, char count)

//=================================================================================




4)実行画面
uart実行画面

5)回路図
UARTテスト

【PIC32MX220F032B】UARTを使ってみる。その2:受信

◆PIC32MX220F032BでUARTをつかってみます。今回は受信割り込みにチャレンジです。



1)レジスター設定
データシートDS61168DのPage179~を参照しました。
割り込みの場合は、U1STAレジスタの「URXISEL」bitを下記の中から選定する必要があります。
・0b11:ReServed
・0b10:6byte受信で割り込みフラグが立つ
・0b01:4byte受信で割り込みフラグが立つ
・0b00:1byte受信で割り込みフラグが立つ
1byteだと汎用性が乏しいので「0b01:4byte」にしました。
マスター(PC)からはコマンドとデータが一緒に送れますね。
あとIEC1レジスタの「U1RXIE」bitを1にするのもお忘れなく

2)ポートの設定
データーシートDS61168DのPage146を参照しました。
U1RXは、RA2、RB6、RA4、RB13、RB2、RC6、RC1、RC3が割り当て可能です。
PRA2の場合の記述例は、
U1RXR = 0b0000;//右辺はPRA2を示します。
TRISAbits.TRISA2 = 1;//入力にしなきゃだめでした。

3)受信
データシートDS61107EのPage21に受信方法が記載されています。
「URXDA=1」の時にU1RXREGレジスターをロードすればいいみたいです。

4-1)割り込み設定の有効
データシートのDS61108Epage15のExample8-2を参照に割り込み有効をしました。
・INTCONbits.MVEC = 1;//Multi_Vector
・asm volatile("ei"); //Enable_Interrup
上記2行を記述する必要があります。
データシートpage15の最後方の行は間違ってるっぽいです。
誤:ie/正:ei これにはクソ時間取られました。
推測するにstatusビットのIEと混同したのでしょうか?
また「STATUSbits.IE = 1;」は記述不可でした。どうして?
「INTCONSET =  0x800;」とありますが
セットするなら「0x1000」ではないでしょうか?

4-2)割り込み関数
DS61168DのPage89にU1RXのベクターアドレスが記載されています。
関数としては一個目はVectorアドレス、2個目はPriorityとなります。
PIC24Fまでの記述方法と異なるので戸惑いました。
また関数のプロトタイプは始めの方に記載しなくてもいいみたい・・・

5)プログラムの例
ハイパーターミナルで4回キーを入力するとエコーバックされる仕様です。
プログラムの例はこちら↓

#include <stdio.h>
#include <plib.h>
#include <p32xxxx.h>
#include <stdlib.h>
//== OSC:8MHz SYSCLK:40MHz=(OSC_8*MUL_20)/(PLLI_2*PLLO_2) ====
#pragma config FNOSC=FRCPLL, POSCMOD=OFF, FPLLIDIV=DIV_2
#pragma config FPLLMUL=MUL_20, FPBDIV=DIV_1, FPLLODIV=DIV_2
#pragma config FWDTEN=OFF, ICESEL=ICS_PGx2
//== void ====================================================
void U1TXstring(unsigned char *tex, char count); //UART_TX_String
unsigned char U1RXstring(void); //UARTReceiveFunction_return(unsigned char)
//== string ==================================================
unsigned char string_box1[15] = "abcdefg¥r¥n" ;
unsigned char rev_data[] = "----¥r¥n"; //UART_receive_string
//== main ====================================================
int main(void) {
//== OSC =================================================
SYSTEMConfigPerformance(40000000); //40MHz
//== PORT ================================================
TRISA = 0x00000000;
TRISB = 0x00000000;
ANSELA = 0x00000000;
ANSELB = 0x00000000;
//== T1CON ===============================================
T1CON = 0x00000000; //Clear
T1CONbits.TON = 0; //Timer1_OFF
T1CONbits.TSIDL = 1; //Idelmode:SleepStop
T1CONbits.TGATE = 0; //Gatetime:OFF
T1CONbits.TCKPS = 0B00; //PS1:1
T1CONbits.TCS = 0; //ClockSource:INT
IEC0bits.T1IE = 0; //Interrupt:None
IPC1bits.T1IP = 0; //InterruptLevel:0
//== UART ================================================
//PORT_SELECT
RPA0R = 0B0001; //U1TX_RPA0
U1RXR = 0B0000; //U1RX_RPA2
TRISAbits.TRISA2 = 1; //U1RX
U1MODE = 0x00000000; //Clear
U1MODEbits.UARTEN = 1; //15_UART_Enable
U1MODEbits.RTSMD = 1; //11_SimplexMode
U1MODEbits.BRGH = 0; //3_StandardSpeed*16
U1STA = 0x00000000; //Clear
U1STAbits.UTXEN = 1; //10_TX_enable
U1STAbits.URXEN = 1; //12_RX_enable
U1STAbits.URXISEL = 0B01; //4ByteReceive_Interrupt
IEC1bits.U1RXIE = 1; //U1RX_Interrupt_Enable
IPC8bits.U1IP = 0B110; //Priority_6
IPC8bits.U1IS = 0B00; //Sub_0
U1BRG = 259; //U1BRG=(Fcy/(16*9600))-1
//========================================================
//== Interrupt ENABLE ===========================================
INTCONbits.MVEC = 1;
asm volatile("ei");
//========================================================
while(1)
{
//delay_ms(200);
//delay_us(1);
}//while(1)
}//int main(void)
//== U1RXInterrupt =========================================================
void __ISR(32, ipl6) U1RXInterrupt(void) //UARTReceiveInterrupt
{
IFS1bits.U1RXIF = 0; //Interrup_Flag_Clear
//== UART_REV ==============================================================
*rev_data = U1RXstring(); //UARTReceiveFunction
U1TXstring(rev_data,6); //EchoBack

}
//== U1TXstring ==============================================================
void U1TXstring(unsigned char *tex, char count)
{
char i;
for(i=0; i<count; i++)
{
while(U1STAbits.UTXBF); //Buffer_empty
U1TXREG = tex[i]; //set_Buffer
}//for(i=0; i<count; i++)
}//void U1string(unsigned char *tex, char count)
//== U1RXstring ==============================================================
unsigned char U1RXstring(void)
{
char i;
for(i=0; i<4; i++) //4byteInterrupt
{
while(!U1STAbits.URXDA); //Buffer_has_data
rev_data[i] = U1RXREG; //SET_Buffer
}//for(i=0; i<count; i++)
return(*rev_data);
}//void U1string(unsigned char *tex, char count)


間違ってたらゴメンね!

6)回路図はこちら
21f400a2.png

【PIC32MX220F032B】UARTを使ってみる。その1:送信

◆PIC32MX220F032BでUARTをつかってみます。手始めに文字列を送信してみます。



1)レジスター設定
データシートDS61107EのPage26に薄らと記述例があります。
ほとんどPIC24Fと同様です。。。

2)ポートの設定
データーシートのPage148を参照にしました。
PIC24Fと違いU1TXはどのピンでも対応という訳ではなく
RPA0Rは可能だけど、RPA1Rは他の機能という感じです。
こちらは記述例が全くないのでトライアンドエラーで何とかしました。
左辺がBit(pin)で右辺が機能となります。U1TXは「0b0001」となります。

3)送信
データシートDS61107EのPage18に送信方法が記載されています。
U1TXREGレジスターにロードすればいいみたいです。

4)プログラムの例
MPLABではターゲットに【PIC32MX220F032B】が無かったので泣く泣くMPLABXを使いました。
ボーレートは9600bpsです。データシートDS61107EのPage14Table21-2を参照しました。
実行は、文字列’abcdefg’と改行とNewラインをずーっとです。
プログラムの例はこちら↓>

#include <stdio.h>
#include <plib.h>
#include <p32xxxx.h>
#include <stdlib.h>
//== OSC:8MHz SYSCLK:40MHz=(OSC_8*MUL_20)/(PLLI_2*PLLO_2) ====
#pragma config FNOSC=FRCPLL, POSCMOD=OFF, FPLLIDIV=DIV_2
#pragma config FPLLMUL=MUL_20, FPBDIV=DIV_1, FPLLODIV=DIV_2
#pragma config FWDTEN=OFF, ICESEL=ICS_PGx2
//== void ====================================================
void U1string(unsigned char *tex, char count);
//== string ==================================================
unsigned char string_box1[15] = "abcdefg¥r¥n" ;
//== main ====================================================
int main(void) {
//== OSC =================================================
SYSTEMConfigPerformance(40000000); //40MHz
//== PORT ================================================
TRISA = 0x00000000;
TRISB = 0x00000000;
//== UART ================================================
RPA0R = 0B0001; //U1TX_RPA0
U1MODE = 0x00000000; //Clear
U1MODEbits.UARTEN = 1; //15_UART_Enable
U1MODEbits.RTSMD = 1; //11_SimplexMode
U1MODEbits.BRGH = 0; //3_StandardSpeed*16
U1STA = 0x00000000; //Clear
U1STAbits.UTXEN = 1; //10_TX_enable
U1BRG = 259; //U1BRG=(Fcy/(16*9600))-1
//========================================================
while(1)
{
U1string(string_box1,9);
//delay_ms(200);
//delay_us(1);
}//while(1)
}//int main(void)

//== U1string ==============================================================
void U1string(unsigned char *tex, char count)
{
char i;
for(i=0; i<count; i++)
{
while(U1STAbits.UTXBF);
U1TXREG = tex[i];
}//for(i=0; i<count; i++)
}//void U1string(unsigned char *tex, char count)

間違ってたらゴメンね!

5)ハイパーターミナルで確認


5)回路図はこちら
df12f96c.png


ギャラリー
  • 【PIC32MZ2048ECH144-I/PH】PIC32MZ2048ECH144を買いました!
  • 【PIC32MX370F512H】タイマーを使ってみる。
  • 【dsPIC33FJ128MC802】PMP接続のDMA転送でaitendoの1.44インチ液晶TFT(ZY-FGD)を使ってみる。その3
  • 【dsPIC33FJ128MC802】PMP接続のDMA転送(連続転送)でaitendoの液晶を使ってみる。
  • 【dsPIC33FJ128MC802】PMP接続のDMA転送(連続転送)でaitendoの液晶を使ってみる。
  • 【dsPIC33FJ128MC802】PMP接続のDMA転送(連続転送)でaitendoの液晶を使ってみる。
  • 【dsPIC33FJ128MC802】PMP接続のDMA転送(連続転送)でaitendoの液晶を使ってみる。
  • 【dsPIC33FJ128MC802】aitendoの1.44インチ液晶TFT(ZY-FGD)をPMP接続で使ってみる!
  • 【dsPIC33FJ128MC802】aitendoの1.44インチ液晶TFT(ZY-FGD)をPMP接続で使ってみる!
メッセージはこちちらからお願いします。

名前
メール
本文
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

ブログパーツ
  • SEOブログパーツ
にほんブログ村 その他趣味ブログ 電子工作へ
にほんブログ村
アクセスカウンタ
アクセスランキング