P PICミニBBシリーズ(23) 〜USB接続でPICを3.3Vで使う
by fjk
今まで、PICはUSB接続5V動作で、3.3V信号が必要なときは、信号レベル変換デバイスを使っていたが、レベル変換デバイスによっては動作が不安定になることがあった。特に、SPI接続デバイスは3.3V動作の物が多いので、PICを3.3Vで動作させると、レベル変換デバイスが不要となる。
USB接続ユニットのシリアル信号には3.3Vと5Vのモノがあり、2種類のユニットをテストした。また、USBユニットから3.3V電源が供給できるものもあるが、拡張性を考慮すると別途3.3Vの電源が必要。もし、USBバスパワー+三端子レギュレータを利用する場合、USBユニットから5Vも取り出せること。
【ハード】
- PICは手持ちのPIC16F1823/25、PIC動作確認のため抵抗(1kΩ)を介してLEDをRC3に接続。
- 三端子レギュレータのパッケージはTO252-3で、TO-252変換基板(#109075、@50)も使用
@ 3.3V出力シリアルのUSBユニット [#番号は秋月電子]
- ・USBシリアル変換モジュール:
- MPL2303SA(マルツ、@894)
5,6,8番端子にはピンを取付けない
- ・三端子レギュレータ:
- NJU7223DL1(3.3V/500mA、#103705、@180)
端子並びに注意!(GNDが中央で無い)
- PL2303SAはドライバーのインストールが必要とあったが、win10(22H2)で接続してみると、自動でドライバーがインストールされ、問題なく接続出来た。
-
A 5V出力シリアルのUSBユニット [#番号は秋月電子]
- ・USBシリアル変換モジュール:
- FT234X(#108461、@780)
- ・三端子レギュレータ:
- NJM2845DL1-33(3.3V/800mA、#111299、@50)
- USBユニットのRx入力はPICのTxが3.3VでもOKなので、そのまま接続。USBユニットのTx信号は2つの固定抵抗で電圧を約3.1Vに分圧してPICのRxに接続した。
-
【ソフト】 @もAも同じ
・MCCの設定
-

system module (INTOSCで16MHz)
|
-

EUSART (115200bps)
|

TMR0 (約1秒毎の割り込みでLED点滅)
|
【abc923-1823/25.c】 abc923-1825.c (zip) [1823.cも同じ]
/*****************************(abc923-1823/25.c)****
* PIC Test (3.3V Power)
****************************************************/
#include "mcc_generated_files/mcc.h"
#include "myProject.h"
//--- タイマー・汎用変数
char Msg[20]; // コメント等送信用文字列
uint8_t TFlg; // タイマーフラグ
//---- EUSART用変数
char RBuf[EU_BFSIZE]; // シリアル受信バッファー
uint8_t SFlg; // シリアル受信フラグ
/***************************************
* タイマ0 Callback関数 (1秒周期割り込み)
***************************************/
void TMR0_Process(void){
TFlg = 1; // タイマーフラグセット
}
/***************************************
* Main application
***************************************/
void main(void){
char cmd;
SYSTEM_Initialize();
// タイマ0 Callback関数定義
TMR0_SetInterruptHandler(TMR0_Process);
INTERRUPT_GlobalInterruptEnable();
INTERRUPT_PeripheralInterruptEnable();
EU_Puts("--- test ---");
LED_SetHigh();
while (1) {
// 1秒周期の処理
if(TFlg){ // フラグオンの場合
LED_Toggle();
TFlg = 0; // フラグリセット
}
// コマンド処理
if(SFlg){ // 受信ありの場合
cmd = RBuf[0];
EU_Write("Input = ");
EU_Puts(RBuf);
SFlg = 0;
}
}
}
/*** End of File ***/
|
・シリアル通信用(mcc_generated_files/eusart.cに2行を追加)
【eusart.c】
/***** (mcc_generated_files/eusart.c )****
* シリアル通信 (赤字の部分を追加)
*********************************************/
#include "eusart.h"
#include "../myProject.h"
・・・・<途中省略>・・・・
void EUSART_Receive_ISR(void)
{
eusartRxStatusBuffer[eusartRxHead].status = 0;
if(RCSTAbits.FERR){
eusartRxStatusBuffer[eusartRxHead].ferr = 1;
EUSART_FramingErrorHandler();
}
if(RCSTAbits.OERR){
eusartRxStatusBuffer[eusartRxHead].oerr = 1;
EUSART_OverrunErrorHandler();
}
if(eusartRxStatusBuffer[eusartRxHead].status){
EUSART_ErrorHandler();
} else {
EUSART_RxDataHandler();
}
// or set custom function using EUSART_SetRxInterruptHandler()
myEusart();
}
・・・<以後省略>・・・
|
・オリジナルライブラリー
【myFunction.c】 myFunction.c + myProject.h(zip)
********************(myFunction.c)******
* 自作汎用関数
****************************************/
#include
#include "myProject.h" // #define EU_BFSIZE
/*** EUSARTシリアル関数用 ********************/
extern char RBuf[]; // 受信文字Buffer
extern uint8_t SFlg; // 受信フラグ
static uint8_t sIdx = 0; // 受信文字列Index
/*--- Eusart受信割り込みハンドラー -------------
* eusrt.cのEUSART_Recive_ISRに追加すること
*---------------------------------------------*/
void myEusart(){
char ch;
ch = EUSART_Read();
#if ECHO == ON
EUSART_Write(ch);
#endif
if((ch == 0x0a)||(ch == 0x0d)){ // 改行処理
RBuf[sIdx] = 0;
sIdx = 0;
SFlg = 1;
}else if((ch == 0x08)&&(sIdx > 0)){ // BS処理
sIdx--;
}else{
if(sIdx < EU_BFSIZE) RBuf[sIdx++] = ch;
}
}
/*--- Eusart受信データを返す--------------------
* *str:受信データを格納する文字列
* RETURN:受信した文字数([0]ならデータ無し)
*---------------------------------------------*/
/*uint8_t EU_gets(char *str){
strcpy(str,rBuf);
return strlen(rBuf);
}
*/
/*--- Eusartへ文字列を送信 ---------------------
* *str:送信したい文字列データ
*---------------------------------------------*/
void EU_Write(char *str){
while(*str != 0){ // 文字列終りまで
EUSART_Write(*str++); // 1文字送信
}
}
/*--- Eusartへ改行を送信 ----------------------*/
void EU_Write_CR(void){
EUSART_Write('\n');
}
/*--- Eusartへ文字列送信(改行付)--------------
* *str:送信したい文字列データ
*---------------------------------------------*/
void EU_Puts(char *str){
EU_Write(str);
EU_Write_CR();
}
/*** 文字列変換関数 **************************/
/*---- 16進文字列を10進数に変換[=xtoi()/C90]----
* *str:10進数に変化したい16進数文字列
* RETURN:変換された32ビット符号無し整数
*---------------------------------------------*/
uint32_t my_xtol(char *str){
uint32_t dec;
dec = strtoul(str,NULL,16);
return (uint32_t)dec;
}
/*--- 下位4ビットを16進数文字に変換 ------------
* n:符号無し16bit整数(最下位の4bitのみ有効)
* RETURN:16進数に対応するアスキー文字
*---------------------------------------------*/
uint8_t my_utoa2(uint16_t n){
n &= 0x0F;
if(n < 10) return '0'+ (uint8_t)n;
else return 'A'+ ((uint8_t)n - 10);
}
/*--- 1ワード(16ビット)を16進文字に変換 -------
* *str:変換結果を格納する文字列
* wd :変換したい符号無し16ビットデータ
* dg :16進数文字列の桁数
*----------------------------------------------*/
void my_utoa(char *str, uint16_t wd, uint8_t dg){
if(dg > 3) *str++ = my_utoa2(wd >> 12);
if(dg > 2) *str++ = my_utoa2(wd >> 8);
if(dg > 1) *str++ = my_utoa2(wd >> 4);
*str++ = my_utoa2(wd);
*str = '\0';
}
/*--- 文字列を逆順に入替 -----------------------
* *str:文字順を入れ替えたい文字列
*-----------------------------------------------*/
void reverseString(char *str) {
uint8_t i, length;
length = (uint8_t)strlen(str);
for (int i = 0; i < length / 2; i++) {
char temp = str[i];
str[i] = str[length - 1 - i];
str[length - 1 - i] = temp;
}
}
/*--- 10進数文字列変換(下位から変換)----------
* *str:変換結果を格納する文字列
* wd :変換したい符号無し16ビットデータ
*-----------------------------------------------*/
void my_itoa2(char *str, uint16_t wd){
uint8_t i;
for(int i = 0; i < 6; i++){
*str++ = '0' + (wd % 10);
wd = wd / 10;
if(wd == 0) break;
}
*str = '\0';
}
/*--- 10進数文字列変換 -------------------------
* *str:変換結果を格納する文字列
* wd :変換したい符号無し16ビットデータ
*-----------------------------------------------*/
void my_itoa(char *str, uint16_t wd){
my_itoa2(str, wd);
reverseString(str);
}
/******* End of File ********/
|
/*********************************(myProject.h)*****
* プロジェクト個別条件指定ファイル 【強化版】 *
* (main.cと同じフォルダーに作成) *
***************************************************/
#include "mcc_generated_files/mcc.h"
#include "string.h"
#define ON 1
#define OFF 0
/***** PIC電源電圧 ***********************/
//--- VCC宣言無しは5V(VCC=50と同じ)
//#define VCC 50 / 電源電圧は5V
#define VCC 33 // 電源電圧は3.3V
/***** EUSARTモジュール *******************/
#define EU_BFSIZE 40
//--- ECHO宣言無しはエコー有り(ECHO ONと同じ)
#define ECHO ON // エコー有り
//#define ECHO OFF // エコー無し
/*=== Eusart受信割り込みハンドラー ==============
* eusrt.cのEUSART_Recive_ISRに追加すること
*---------------------------------------------*/
void myEusart();
/*=== 文字列シリアル出力関数 ===*/
//--- Eusartへ文字列送信
/* *str: 出力する文字列
* --------------------------- */
void EU_Write(char *str);
//--- Eusartへ改行を送信
void EU_Write_CR(void);
//--- Eusartへ文字列送信(改行付)
/* *str: 出力する文字列
* --------------------------- */
void EU_Puts(char *str);
/****** Delay Macros ********/
#define __delay_us(x) _delay((uint32_t)((x)*(_XTAL_FREQ/4000000.0)))
#define __delay_ms(x) _delay((uint32_t)((x)*(_XTAL_FREQ/4000.0)))
/*** 自作汎用関数 *******/
/*== 文字列変換関数 ===========*/
//---- 16進文字列を10進数に変換
uint32_t my_xtol(char *str);
//--- 16進数(負号無し)を文字列に変換
void my_utoa(char *str, uint16_t wd, uint8_t dg);
//--- 10進数(符号無し)を文字列に変換
void my_itoa(char *str, uint16_t wd);
/******* End of File ********/
|
※プログラムのリストをハイライト付きのスタイルで見る場合はここをクリック
※ 本レポートの参考・利用は、あくまでも自己責任でお願いします。