8ピンの32bitマイコンSTM32C011J4M7にI2CとUARTをつなごうと思い,制約がないピンにUARTの送信機能だけを持たせてみました。
UARTが使えるとシリアルモニタなどにデータを表示・保存できたり,プログラムの動きの確認などにもちょこっと使えて便利です。
[ハードの接続]
センサーなどにI2C接続するマイコン側ではI2Cに使えるピンはハード的にあらかじめ大体決まっていて,STM32C011J4M7でI2Cを使うと,電源やプログラムの書き込みなどに気を使わないピンは残るPB7の1本だけです(^^;;;;
このPB7を使ってソフト的にUARTの送信機能を持たせてみました。
![](https://stat.ameba.jp/user_images/20240224/22/pta55/bb/b5/j/o1284053415405571692.jpg?caw=800)
データの受け側としてはST-LINKのシリアルRxに接続しました。
![](https://stat.ameba.jp/user_images/20240224/22/pta55/79/c6/j/o0926069615405571689.jpg?caw=800)
[ソフトでUART送信」
用意されているハード的なUART機能はプログラムが大きく,また使用ピンが指定されるので,手作りにしました。
9600bpsや115200bpsなどのゆっくりした速度なら普通のデジタル出力とディレイでそれなりに波形が作れると思いますV(^^)。
この2つの計算上のパルス幅を意識した定数を使って,1byteの送信ルーチンをまず作ってみました。
9600bps:1000000/9600=104.17 us
115200bps:1000000/115200=8.68 us
下図は数値0x55を出力してロジアナでみた各bps用の波形です。
・9600bps 1パルス:約104.8 us
![](https://stat.ameba.jp/user_images/20240224/22/pta55/86/59/j/o0927017815405571706.jpg?caw=800)
・115200bps 1パルス:約8.3 us
![](https://stat.ameba.jp/user_images/20240224/22/pta55/51/2d/j/o0929017415405571710.jpg?caw=800)
115200bpsは少し危うい気もしますが,エラーも出ずに動いてはくれています
ま,もしエラーが出るようならnop的なのを入れて微調整ですね(^^;;;;;。
波形は何とかできましたので,もう少し便利に使えるように,キャラクタと数値の表示ルーチンを追加したテストプログラムです。
上のプログラムの出力結果です。
![](https://stat.ameba.jp/user_images/20240224/23/pta55/dd/af/j/o0786047915405607461.jpg?caw=800)
数値出力は5桁の"unsigned int" ぐらいまでにしていますが,ここは必要に応じてちょこちょこした方がプログラムはシンプルにできそうです(^^)。
以上のように,UARTでもゆっくりした速度で勝手な時に出力するだけならそうは難しくないのですが,半二重ってどうやって切り替えているのでしょうかね。できれば小さなマイコンでは重宝するのですけど,,,。
UARTが使えるとシリアルモニタなどにデータを表示・保存できたり,プログラムの動きの確認などにもちょこっと使えて便利です。
[ハードの接続]
センサーなどにI2C接続するマイコン側ではI2Cに使えるピンはハード的にあらかじめ大体決まっていて,STM32C011J4M7でI2Cを使うと,電源やプログラムの書き込みなどに気を使わないピンは残るPB7の1本だけです(^^;;;;
このPB7を使ってソフト的にUARTの送信機能を持たせてみました。
![](https://stat.ameba.jp/user_images/20240224/22/pta55/bb/b5/j/o1284053415405571692.jpg?caw=800)
データの受け側としてはST-LINKのシリアルRxに接続しました。
![](https://stat.ameba.jp/user_images/20240224/22/pta55/79/c6/j/o0926069615405571689.jpg?caw=800)
[ソフトでUART送信」
用意されているハード的なUART機能はプログラムが大きく,また使用ピンが指定されるので,手作りにしました。
9600bpsや115200bpsなどのゆっくりした速度なら普通のデジタル出力とディレイでそれなりに波形が作れると思いますV(^^)。
この2つの計算上のパルス幅を意識した定数を使って,1byteの送信ルーチンをまず作ってみました。
9600bps:1000000/9600=104.17 us
115200bps:1000000/115200=8.68 us
// uart Tx Pin :PB7 (STM32C011J Pin 1)
#define uTx_pin PB7
//const byte uTx_bms=104 ; // delay for 9600bps
const byte uTx_bms=7 ; // 115200bps
void setup() {
delay(3000); // waiting for upload
pinMode(uTx_pin, OUTPUT);
digitalWrite(uTx_pin, HIGH);
}
void loop() {
uTx_byte(0x55); // Send 0b01010101
delay(10);
}
void uTx_byte(byte sval){
digitalWrite(uTx_pin, LOW); // start bit
delayMicroseconds(uTx_bms);
for (byte i=0; i < 8; i++){
digitalWrite(uTx_pin, bitRead(sval,i));
delayMicroseconds(uTx_bms);
}
digitalWrite(uTx_pin, HIGH); // 1 stop bit
delayMicroseconds(uTx_bms);
}
下図は数値0x55を出力してロジアナでみた各bps用の波形です。
・9600bps 1パルス:約104.8 us
![](https://stat.ameba.jp/user_images/20240224/22/pta55/86/59/j/o0927017815405571706.jpg?caw=800)
・115200bps 1パルス:約8.3 us
![](https://stat.ameba.jp/user_images/20240224/22/pta55/51/2d/j/o0929017415405571710.jpg?caw=800)
115200bpsは少し危うい気もしますが,エラーも出ずに動いてはくれています
ま,もしエラーが出るようならnop的なのを入れて微調整ですね(^^;;;;;。
波形は何とかできましたので,もう少し便利に使えるように,キャラクタと数値の表示ルーチンを追加したテストプログラムです。
// uart Tx Pin :PB7 (STM32C011J Pin 1)
#define uTx_pin PB7
//const byte uTx_bms=104 ; // delay for 9600bps
const byte uTx_bms=7 ; // 115200bps
void setup() {
delay(3000); // waiting for upload
pinMode(uTx_pin, OUTPUT); // set pin as output
digitalWrite(uTx_pin, HIGH);
}
void loop() {
uTx_str("Test:");
for (int i=0; i < 20; i++){
uTx_digit5(i);
if (i <19){uTx_byte(',');}
}
uTx_byte(0x0D); uTx_byte(0x0A); // CR,LF
delay(100);
} // loop end
/* Tx character string*/
void uTx_str( char d[]){
for(byte i=0; i < sizeof(d)+1; i++){
uTx_byte(d[i]);
}
}
/* Tx 5_digit number, Ascii cord */
void uTx_digit5( int d){
uTx_byte(d/10000+0x30);
uTx_byte((d%10000)/1000+0x30);
uTx_byte((d%1000)/100+0x30);
uTx_byte((d%100)/10+0x30);
uTx_byte(d%10+0x30);
}
/* Tx 1_byte */
void uTx_byte(byte d){
digitalWrite(uTx_pin, LOW); // start bit
delayMicroseconds(uTx_bms);
for (byte i=0; i < 8; i++){ // data bit0-7
digitalWrite(uTx_pin, bitRead(d,i));
delayMicroseconds(uTx_bms);
}
digitalWrite(uTx_pin, HIGH); // 1 stop bit
delayMicroseconds(uTx_bms);
}
上のプログラムの出力結果です。
![](https://stat.ameba.jp/user_images/20240224/23/pta55/dd/af/j/o0786047915405607461.jpg?caw=800)
数値出力は5桁の"unsigned int" ぐらいまでにしていますが,ここは必要に応じてちょこちょこした方がプログラムはシンプルにできそうです(^^)。
以上のように,UARTでもゆっくりした速度で勝手な時に出力するだけならそうは難しくないのですが,半二重ってどうやって切り替えているのでしょうかね。できれば小さなマイコンでは重宝するのですけど,,,。