0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PIC18とRPI4Bのuart通信 0. Hello

Last updated at Posted at 2024-12-24

ラズパイ5は、AIハット、AIカメラも発売され、大変話題です。さらにPCIe搭載のCompute Module 5も発売されて、アカデミックで設立されたラズベリーですが、ついに株式上場もしました。ただし今回は、今では少しレトロになってしまったRPI4Bを使います。このRPI4BとMicrochip社のPIC18との、2.304MbpsでのUART高速通信を試行しました。

1.png
配線図です。今回使うPIC18F2620は5Vです。一方、RPI4Bのロジックレベルは3.3Vです。レベル変換には秋月電子通商のFXMA108を使いました。(OEピンを10KΩで5Vのhighにプルアップしてdisable状態です。PIC起動時にプログラム上からlowにしてenableにしています。)そしてブレッドボードでは失敗したので、ユニバーサル基板にハンダ付しました。さらに0.2sqの単線(撚り線ではなく)を使用しました。実行結果は、2.304Mbpsでは延長50cmでした。1mまで延長すると、460Kbpsまで落ちました。明らかに、通信速度は、導線の長さでした。

次は、今回使用したラズパイ側のPythonプログラムです。BookwormのPython 3.11.2をThonny上で動作させています。またRPI4BのUARTは、Serial Consoleをオフ、Serialをオンにしただけの簡易設定です。mini PORTのUARTです。
先にPICを起動し、受信待機状態にします。
RPI4BのThonnyから、"Hello PIC Im Pi.Hello PIC Im Pi." をPICへ送信します。
Thonnyで、"HELLO Pi Im PIC@" をPICから受信すれば、2.304MbpsでのUART送受信が成功です。
同じRPI4BでBuster(x32)とBookworm(x64)を試してみましたが、どちらも以下のプログラムで動きます。Buster(x32)の方が、V2カメラ・画像解析のソフトが充実・完成しているので、現実的には使い易いですが。

#RPI-0-uart-tx.py
#Serial Console OFF, Serial ON
#RPI4B Buster(x32) Python 3.7.3 (x32) Thonny, and RUN  or 
#RPI4B bookworm(x64) Python 3.11.2 Thonny, and RUN

import serial

#Open SERIALttyS0
SERIALttyS0 = serial.Serial('/dev/ttyS0', 2304000, timeout=1)

#Set SendMessage
SendMessage = "Hello PIC Im Pi.Hello PIC Im Pi."
#Send Command
SERIALttyS0.write(SendMessage.encode())

#Receive ReturnMessage and print
binary_ReturnMessage = SERIALttyS0.readline()
ReturnMessage = binary_ReturnMessage.decode()
print(ReturnMessage)

#Close SERIALttyS0
SERIALttyS0.close()

次はPIC側、つまりPIC18F2620のXC8プログラムです。Microchip社のMPLAB XIDEとXC8を使います。開発環境は、x64ビットWindowsパソコン用のMPLAB X IDE v6.00とXC8 Compiler v2.4.0です。PICkit3が使える最終版です。また26K22でも、プログラム中でコメントアウトしているconfigとアナログ設定を入れ替えるだけで、動きます。PIC18F2620と26K22の相違点は多いですが、今回のUARTに関しては同じです。

//main.c    MPLAB  X IDE v6.00,  XC8 Compiler v2.4.0
#include <xc.h>

#define _XTAL_FREQ 36864000

#define LED_A0	LATA1
#define FXMA_CS0_TRIS	TRISC0
#define FXMA_CS0_IO	LATC0

//2620
#pragma config OSC = HSPLL
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config PWRT = ON
#pragma config BOREN = OFF
#pragma config BORV = 3
#pragma config WDT = OFF
#pragma config WDTPS = 32768
#pragma config CCP2MX = PORTC
#pragma config PBADEN = OFF
#pragma config LPT1OSC = OFF
#pragma config MCLRE = ON
#pragma config STVREN = OFF
#pragma config LVP = OFF
#pragma config XINST = OFF
#pragma config CP0 = OFF
#pragma config CP1 = OFF
#pragma config CP2 = OFF
#pragma config CP3 = OFF
#pragma config CPB = OFF
#pragma config CPD = OFF
#pragma config WRT0 = OFF
#pragma config WRT1 = OFF
#pragma config WRT2 = OFF
#pragma config WRT3 = OFF
#pragma config WRTC = OFF
#pragma config WRTB = OFF
#pragma config WRTD = OFF
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF
#pragma config EBTR2 = OFF
#pragma config EBTR3 = OFF
#pragma config EBTRB = OFF
////26k22
//#pragma config FOSC = HSHP
//#pragma config PLLCFG = ON
//#pragma config PRICLKEN = ON
//#pragma config FCMEN = OFF
//#pragma config IESO = OFF
//#pragma config PWRTEN = ON
//#pragma config BOREN = OFF
//#pragma config BORV = 190
//#pragma config WDTEN = OFF
//#pragma config WDTPS = 32768
//#pragma config CCP2MX = PORTC1
//#pragma config PBADEN = OFF
//#pragma config CCP3MX = PORTB5
//#pragma config HFOFST = OFF
//#pragma config T3CMX = PORTC0
//#pragma config P2BMX = PORTB5
//#pragma config MCLRE = EXTMCLR
//#pragma config STVREN = OFF
//#pragma config LVP = OFF
//#pragma config XINST = OFF
//#pragma config CP0 = OFF
//#pragma config CP1 = OFF
//#pragma config CP2 = OFF
//#pragma config CP3 = OFF
//#pragma config CPB = OFF
//#pragma config CPD = OFF
//#pragma config WRT0 = OFF
//#pragma config WRT1 = OFF
//#pragma config WRT2 = OFF
//#pragma config WRT3 = OFF
//#pragma config WRTC = OFF
//#pragma config WRTB = OFF
//#pragma config WRTD = OFF
//#pragma config EBTR0 = OFF
//#pragma config EBTR1 = OFF
//#pragma config EBTR2 = OFF
//#pragma config EBTR3 = OFF
//#pragma config EBTRB = OFF

static unsigned char vBANK01[256];
static unsigned char vBuffer[32];

near uint8_t i;
near unsigned char Temp1;
near uint16_t Wi, Wi_last;
near uint32_t Di;


void main()
{
    //Analog setting 2620
    ADCON0 = 0x00;
    ADCON1 = 0x0F;
    ////Analog setting 26k22
    //ANSELA = 0b00100000 ;    // AN4(RA5)
    //ANSELB = 0b00000000 ;
    //ANSELC = 0b00000000 ;
    
    TRISA  = 0b00100000 ;    // RA5
    TRISB  = 0b00000000 ;
    TRISC  = 0b00000000 ;
    PORTA  = 0b00000000 ;
    PORTB  = 0b00000000 ;
    PORTC  = 0b00000000 ;
    
    // C port	//1		0	0	1	0	0	0	0
    //			//RX	TX	SDO	SDI	SCK	C2	C1	C0
    TRISC = 0x90;
    
    // TXSTA	//0		0	1		0		0	1		0		0
    //			//CSRC	TX9	TXEN	SYNC	-	BRGH	TRMT	TX9D
    TXSTA = 0x24;
    
    // RCSTA	//1		0	0		1		0		0		0		0
    //			//SPEN	RX9	SREN	CREN	ADDEN	FERR	OERR	RX9D
    RCSTA = 0x90;
    
    // BAUDCON	//0			0		0		0		0		0	0	0
    //			//ABDOVF	RCIDL	RXDTP	TXCKP	BRG16	-	WUE	ABDEN
    BAUDCON = 0x00;	
    
    // SPBRG	(36.864 MHz)	
    // SPBRG = 0x13,  013H=19, 36.864/(16(1+19)) =	115.2 Kbps
    // SPBRG = 0x04,  004H=4,  36.864/(16(1+4))  =	460.8 Kbps
    // SPBRG = 0x01,  001H=1,  36.864/(16(1+1))  =	1.152 Mbps
    // SPBRG = 0x00,  000H=0,  36.864/(16(1+0))  =	2.304 Mbps
    SPBRG = 0x00;
    
    FXMA_CS0_TRIS =0;
    FXMA_CS0_IO=0;
    
    Wi=0;
    Wi_last=31;
    for(; ; )
    {
        if (RCSTAbits.OERR)
        {
            RCSTAbits.CREN = 0;
            Temp1 = RCREG;
            RCSTAbits.CREN = 1;
        }
        if(RCIF==1) 
        {
            vBANK01[Wi]  = RCREG;
            Wi++;
        }
        if(Wi>Wi_last) {  break;  }
   }
   
    vBuffer[0] =0x48;  // H
    vBuffer[1] =0x45;  // E
    vBuffer[2] =0x4C;  // L
    vBuffer[3] =0x4C;  // L
    vBuffer[4] =0x4F;  // O
    vBuffer[5] =0x20;  // 
    vBuffer[6] =0x50;  // P
    vBuffer[7] =0x69;  // i
    vBuffer[8] =0x20;  // 
    vBuffer[9] =0x49;  // I
    vBuffer[10]=0x6D;  // m
    vBuffer[11]=0x20;  // 
    vBuffer[12]=0x50;  // P
    vBuffer[13]=0x49;  // I
    vBuffer[14]=0x43;  // C
    vBuffer[15]=0x40;  // @
    vBuffer[16]=0x0A;  // LF
    
    Wi=0;
    Wi_last=17;
    for(; ; )
    {
        if(TRMT==1) 
        {
            TXREG  =  vBuffer[Wi];
            Wi++;
        }
        if(Wi>Wi_last) {  break;  }
    }
    
    FXMA_CS0_IO=1;
    
    while(1) {
        LED_A0 = 0;
        __delay_ms(250) ;
        LED_A0 = 1;
        __delay_ms(250) ;
     }
}

さらに今回は、x32ビットのWindowsパソコン用のMPLAB IDEとC18でも作成しました。なんとネットに接続していない自閉症のWin7の登場です。また2620は、いにしえの秋月プログラマーキットの時代に使っていましたから、懐かしい顔ぶれが揃っています。お久しぶり。話がそれましたが、ここでの開発環境は、x32ビットのWindowsパソコン用の最終版のMPLAB_IDE_8_92とMPLAB_C18_3.46です。PICkit3を使います。インラインアセンブリングが散在しています。一方、XC8はC18と全く異なるので、XC8ではインラインアセンブリングを全く使いません。PICは5年ほど全く使っていなかったので、レトロなUART通信を再試行するのに、少し苦労しました。includeに必要なHardwareProfile.hとConfiguration Bitsの画面コピーも添付します。

// MainDemo.c     MPLAB_IDE_8_92,  MPLAB_C18_3.46
#include <p18f2620.h>
//#include <p18f26k22.h>
#include <GenericTypeDefs.h>
#include <delays.h>
#include <HardwareProfile.h>

#pragma udata bank1  = 0x100
static unsigned char vBANK01[256];
#pragma udata bank2 = 0x200
static unsigned char vBuffer[32];

#pragma udata access my_access
near unsigned char Temp1;
near BYTE i;
near WORD Wi;
near DWORD Di;


#pragma code
void main(void){

	//2620
	ADCON0 = 0x00;
	ADCON1 = 0x0F;
 
	////26k22
	//ANSELA = 0b00100000 ;    // AN4(RA5)
	//ANSELB = 0b00000000 ;
	//ANSELC = 0b00000000 ;
 
	TRISA  = 0b00100000 ;    // RA5
	TRISB  = 0b00000000 ;
	TRISC  = 0b00000000 ;
	PORTA  = 0b00000000 ;
	PORTB  = 0b00000000 ;
	PORTC  = 0b00000000 ;
 
	// C port	//1		0	0	1	0	0	0	0
	//			//RX	TX	SDO	SDI	SCK	C2	C1	C0
	TRISC = 0x90;
 
	// TXSTA	//0		0	1		0		0	1		0		0
	//			//CSRC	TX9	TXEN	SYNC	-	BRGH	TRMT	TX9D
	TXSTA = 0x24;
 
	// RCSTA	//1		0	0		1		0		0		0		0
	//			//SPEN	RX9	SREN	CREN	ADDEN	FERR	OERR	RX9D
	RCSTA = 0x90;
 
	// BAUDCON	//0			0		0		0		0		0	0	0
	//			//ABDOVF	RCIDL	RXDTP	TXCKP	BRG16	-	WUE	ABDEN
	BAUDCON = 0x00;	
 
	// SPBRG	(36.864 MHz)	
	// SPBRG = 0x13,  013H=19, 36.864/(16(1+19)) =	115.2 Kbps
	// SPBRG = 0x04,  004H=4,  36.864/(16(1+4))  =	460.8 Kbps
	// SPBRG = 0x01,  001H=1,  36.864/(16(1+1))  =	1.152 Mbps
	// SPBRG = 0x00,  000H=0,  36.864/(16(1+0))  =	2.304 Mbps
	SPBRG = 0x00;
 
	LED0_IO = 0;
 
	FXMA_CS0_TRIS = 0;
	FXMA_CS0_IO = 0;
 
	for(Wi = 0; Wi < 32; Wi++)
	{
		if (RCSTAbits.OERR) 
		{
			RCSTAbits.CREN = 0;
			Temp1 = RCREG;
			RCSTAbits.CREN = 1;
		}
		_asm BTFSS  PIR1, 5, 0 _endasm      // RCIF in P1R1 = 5
		_asm BRA -2	       _endasm
		vBANK01[Wi]  = RCREG;
	}
 
	vBuffer[0] =0x48;  // H
	vBuffer[1] =0x45;  // E
	vBuffer[2] =0x4C;  // L
	vBuffer[3] =0x4C;  // L
	vBuffer[4] =0x4F;  // O
	vBuffer[5] =0x20;  // 
	vBuffer[6] =0x50;  // P
	vBuffer[7] =0x69;  // i
	vBuffer[8] =0x20;  // 
	vBuffer[9] =0x49;  // I
	vBuffer[10]=0x6D;  // m
	vBuffer[11]=0x20;  // 
	vBuffer[12]=0x50;  // P
	vBuffer[13]=0x49;  // I
	vBuffer[14]=0x43;  // C
	vBuffer[15]=0x40;  // @
	vBuffer[16]=0x0A;  // LF
 
	for(i = 0; i < 18; i++)		
	{
		_asm BTFSS TXSTA, 1, 0 _endasm      // TRMT in TXSTA = 1
		_asm BRA   -2	       _endasm
		TXREG  =  vBuffer[i];
	}
 
	FXMA_CS0_IO = 1;
 
	while(1){
		LED0_IO = 0;
		Delay10KTCYx(250);
		LED0_IO = 1;
		Delay10KTCYx(250);
	}		
}
#pragma tmpdata

C18用のHardwareProfile.hです。

// HardwareProfile.h         MPLAB_IDE_8_92,  MPLAB_C18_3.46
#ifndef __HARDWARE_PROFILE_H
#define __HARDWARE_PROFILE_H
// Clock frequency value.  This value is used to calculate Tick Counter value
	#define GetSystemClock()		(36864000ul)		// 9.216MHz  Crystal,  PLL x4
	#define GetInstructionClock()	(GetSystemClock()/4)
	#define GetPeripheralClock()	GetInstructionClock()
// IO pins
	#define 	LED0_TRIS		(TRISAbits.TRISA1)	// LED
	#define 	LED0_IO			(LATAbits.LATA1)
	#define 	FXMA_CS0_TRIS	(TRISCbits.TRISC0)	// fxma OE
	#define 	FXMA_CS0_IO		(LATCbits.LATC0)
#endif

C18用2620のConfiguration Bitsの画面コピーです。
Configuration Bits PIC18F2620 .png

C18用26K22のConfiguration Bitsの画面コピーです。
Configuration Bits PIC18F26K22.png

次回は、今回は確認できなかったPICが受信した文字を、キャラクターlcdに表示します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?