fc2ブログ

ロケット・ササキを読む

 「ロケット・ササキ:ジョブズが憧れた伝説のエンジニア・佐々木正」という本を、先日図書館で見つけたので、読んでみました。 佐々木正氏の名前は、元シャープの方でカシオとの「電卓戦争」の中心人物であることは知っていました。20年以上前の学生時代にNHKテレビで放送された「電子立国日本の自叙伝」で登場されていたのを覚えていたからです。このテレビ番組には大変感銘を受けたので今でもよく覚えています。 この「ロケット・ササキ」もそのような内容かなと興味を持ちつつ読み進めていきました。シャープ創業者の早川徳次氏との関係、スティーブ・ジョブズ氏、孫正義氏との交流、仕事に対する「共創」という考え方など、楽しく読むことができました。佐々木氏に対しては、「国賊」などの悪評価等ありますが、私には、「優秀なエンジニアであり、時代の先をいつも見ているスケールの大きな人物」に見えました。最近、このようなエンジニア兼経営者はいないような気がします。
スポンサーサイト



4桁7セグで遊ぶ(2)

 今回も前回に引き続いて、PICを用いて4桁7セグで遊びました。PCからシリアル通信でPIC側に指令を出し、その指令に基づいて7セグを制御しました。PICのシリアル通信(USART通信)の割り込み処理部分の理解に苦しみ、手こずってしまいました・・。
 PIC側の基板は写真の通りで、USART用ピンとI2C(SPI)用ピンを追加配線しました。PIC基板170226
PIC_7seg制御回路図170226
 プログラムは、前回のプログラムにUSART通信部分を追加する形で進めましたが、7セグ表示と同居すると、通信がうまく行かなかったり、表示がうまく行かなかったりと難儀しました。割り込みがうまく行っていないのかなとも考え、深みにはまっていました。最終的には、このサイトのライブラリ類(skUARTlib.c、skUARTlib.h)を参考にさせていただくことでうまく行きました。大変感謝です・・。

//----------------------------------------------
// 7seg control program for PIC16F873A
//----------------------------------------------

// CONFIG
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "skUARTlib.h"

#define _XTAL_FREQ 20000000 /* for delay use */
#define UART_RX_SIZE 5

char rbuf[8];
char sbuf[8];
char cdig[2];
int i, n;
int idig[5];

//segment character
const unsigned char cSeg[11] = {
// .GFEDCBA // pattern
0b00111111, // 0
0b00000110, // 1
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101, // 6
0b00100111, // 7
0b01111111, // 8
0b01101111, // 9
0b10000000 // period
};

//dot character
const unsigned char cDot[8]={
0b00000000, //OFF
0b00000001, //D1
0b00000010, //D2
0b00000011, //D1+D2
0b00000100, //D3
0b00000101, //D1+D3
0b00000110, //D2+D3
0b00000111, //D1+D2+D3
};

//initialize PIC
void InitPic(void)
{
//PortA
// bit0:RA0 2 Out(0) DEG1 COM
// bit1:RA1 3 Out(0) DEG2 COM
// bit2:RA2 4 Out(0) DEG3 COM
// bit3:RA3 5 Out(0) DEG4 COM
// bit4:RA4 6 Out(0)
// bit5:RA5 7 Out(0) DEG5 COM
// bit6:RA6 - Out(0)
// bit7:RA7 - Out(0)
TRISA = 0b00000000;

//PortB
// bit0:RB0 21 Out(0) SEG A
// bit1:RB1 22 Out(0) SEG B
// bit2:RB2 23 Out(0) SEG C
// bit3:RB3 24 Out(0) SEG D
// bit4:RB4 25 Out(0) SEG E
// bit5:RB5 26 Out(0) SEG F
// bit6:RB6 27 Out(0) SEG G
// bit7:RB7 28 Out(0) SEG DP
TRISB = 0b00000000;

//PortC
// bit0:RC0 11 Out(0)
// bit1:RC1 12 Out(0)
// bit2:RC2 13 Out(0)
// bit3:RC3 14 Out(0)
// bit4:RC4 15 Out(0)
// bit5:RC5 16 Out(0)
// bit6:RC6 17 Out(0) TX
// bit7:RC7 18 IN(1) RX
TRISC = 0b10000000;

//IO Initialize
PORTA = 0b00000000;
PORTB = 0b00000000;
PORTC = 0b00000000;
}

//interrupt
void interrupt InterFunction(void){
InterUART(); // USARTの受信割り込み
}

//7seg digit set
void SetDigit(int dg1,int dg2,int dg3,int dg4,int dot){

RA0=1;
PORTB=cSeg[dg1];
__delay_ms(1);
RA0=0;
PORTB = 0b00000000;

RA1=1;
PORTB=cSeg[dg2];
__delay_ms(1);
RA1=0;
PORTB = 0b00000000;

RA2=1;
PORTB=cSeg[dg3];
__delay_ms(1);
RA2=0;
PORTB = 0b00000000;

RA3=1;
PORTB=cSeg[dg4];
__delay_ms(1);
RA3=0;
PORTB = 0b00000000;

RA5=1;
PORTB=cDot[dot];
__delay_ms(1);
RA5=0;
PORTB = 0b00000000;

}

//wait
void Wait(int num){
do{
__delay_ms(10);
}while(--num>0);
}

//main
void main(void){

InitPic();

//USART初期化(8bit,StopBit:1, No Parity, No flow,19200bps)
InitUART(64);

while(1){
//受信待ち
if (UART_Available() != 0) {
//データ受信
n = 0;
memset(rbuf,0,strlen(rbuf));//データバッファ初期化
while(UART_Available() != 0) {
rbuf[n] = UART_Read();//受信
n++;
Wait(1);
}

//データ送信(確認用)
i=0;
memset(sbuf,0,strlen(sbuf));//データバッファ初期化
while(i
sbuf[i] = rbuf[i];
i++;
}
sbuf[i] = 0x0d;//CR
sbuf[i+1] = 0x0a;//LF
UART_Send(sbuf,n+2);//送信

UART_Flush();//受信バッファクリア

for(int i=0;i<5;i++){
memset(cdig,0,strlen(cdig));//初期化
strncpy(cdig,sbuf+i,1); //1文字抽出
cdig[1]='\0';
idig[i]=atoi(cdig);
}
}
//表示
SetDigit(idig[0],idig[1],idig[2],idig[3],idig[4]);
}
}
 106, 157, 161, 165, 166, 180, 182行目のUART関連の命令は、ライブラリ類(skUARTlib.c、skUARTlib.h)の関数です。
 TeraTermを起動し、以下の設定をしました。teraterm設定画面1_170226teraterm設定画面2_170226 PCとのシリアル通信は、以前のブログで紹介したMAX3232ECPEを用いた信号変換基板を使用しています。ターミナルから「12345」のデータを送信した結果、設計通りの結果が表示されました。5文字目の5は、ドットのD1とD3を表示する指令です。res_1234_170226.png続いて、「67891」と「22222」のデータを送信しても、正しく表示されました。teraterm実行画面_170226res_6789_170226.pngres_2222_170226.png 苦労しましたが、やっとここまで来ることが出来ました。次は、PICを用いて、「温湿度、気圧センサ」のデータを取り込んでみようと思います。

4桁7セグで遊ぶ(1)

 前回にて、PIC16F873A(28pin)用のPIC Writerを準備できましたので、今回は「4桁7セグ」の準備です。
 1桁7セグは以前使ったことがありましたが、4桁は今回が初めてです。使用した4桁7セグは、OptoSupply製のOSL40391-LBです。16pinのデバイスで配線図は以下の通りです。OSL40391-LX_170211.png 配線図から判断すると、各桁について、共通の7セグ(A~G)、デシマルポイント(DP)と、その桁自身のカソードコモンがある構成です。カソードコモンを切り替えることで4桁を制御するようです。カソードコモンは各桁の切り替え以外に、ドット(D1~D3)を制御するためのものがあります。

 配線は理解できましたが、いかに4桁を制御するかをネットで調べていた所、「ダイナミック点灯」を用いれば良いことが分かりました。内容解説サイトによると、短時間に一つの桁を光らせ、すぐ次の桁を光らせることを高速(数10msec程度)で繰り返すことで、ある瞬間は一つの桁だけが点灯しているが、人間の目には残像現象があるため、あたかも各桁が連続して点灯しているように見えるとのこと。なるほど、なるほどです。
 4桁7セグの基板への配線は、PICの他に、Raspberry PiやArduinoでも使えるように、入力信号部は14pinのピンヘッダを利用しました。基板配線図は以下の通り。7seg-4_circuit_170211.png 完成品はこんな感じです。7seg-4_170211.png 配線基板も完成しましたので、簡単なPICのプログラムを組んで動作確認です。以下のプログラムをMPLAB X IDEで作成し、前回作製した、簡易PIC WriterでPIC16F873Aに書き込みました。 L.92~L.123のSetDigit関数に「ダイナミック点灯」を仕込んでいます。ここでは1msecで切り替えています。
//----------------------------------------------
// 7seg control program for PIC16F873A
//----------------------------------------------

// CONFIG
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>

#define _XTAL_FREQ 20000000 /*delay関数に必要*/

//segment character
const unsigned char cSeg[11] = {
// .GFEDCBA // pattern
0b00111111, // 0
0b00000110, // 1
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101, // 6
0b00100111, // 7
0b01111111, // 8
0b01101111, // 9
0b10000000, // .
};

//dot character
const unsigned char cDot[8]={
0b00000000, //OFF
0b00000001, //D1
0b00000010, //D2
0b00000011, //D1+D2
0b00000100, //D3
0b00000101, //D1+D3
0b00000110, //D2+D3
0b00000111, //D1+D2+D3
};

//initialize PIC
void InitPic(void)
{
//PortA
// bit0:RA0 2 Out(0) DEG1 COM
// bit1:RA1 3 Out(0) DEG2 COM
// bit2:RA2 4 Out(0) DEG3 COM
// bit3:RA3 5 Out(0) DEG4 COM
// bit4:RA4 6 Out(0)
// bit5:RA5 7 Out(0) DEG5 COM
// bit6:RA6 - Out(0)
// bit7:RA7 - Out(0)
TRISA = 0b00000000;

//PortB
// bit0:RB0 21 Out(0) SEG A
// bit1:RB1 22 Out(0) SEG B
// bit2:RB2 23 Out(0) SEG C
// bit3:RB3 24 Out(0) SEG D
// bit4:RB4 25 Out(0) SEG E
// bit5:RB5 26 Out(0) SEG F
// bit6:RB6 27 Out(0) SEG G
// bit7:RB7 28 Out(0) SEG DP
TRISB = 0b00000000;

//PortC
// bit0:RC0 11 Out(0)
// bit1:RC1 12 Out(0)
// bit2:RC2 13 Out(0)
// bit3:RC3 14 Out(0)
// bit4:RC4 15 Out(0)
// bit5:RC5 16 Out(0)
// bit6:RC6 17 Out(0)
// bit7:RC7 18 Out(0)
TRISC = 0b00000000;

//IO Initialize
PORTA = 0b00000000;
PORTB = 0b00000000;
PORTC = 0b00000000;
}

void SetDigit(int dg1,int dg2,int dg3,int dg4,int dot){

RA0=1;
PORTB=cSeg[dg1];
__delay_ms(1);
RA0=0;
PORTB = 0b00000000;

RA1=1;
PORTB=cSeg[dg2];
__delay_ms(1);
RA1=0;
PORTB = 0b00000000;

RA2=1;
PORTB=cSeg[dg3];
__delay_ms(1);
RA2=0;
PORTB = 0b00000000;

RA3=1;
PORTB=cSeg[dg4];
__delay_ms(1);
RA3=0;
PORTB = 0b00000000;

RA5=1;
PORTB=cDot[dot];
__delay_ms(1);
RA5=0;
PORTB = 0b00000000;
}

void main(void){

int count = 0;
int a = 0;
int b = 1;
int c = 2;
int d = 3;
int e = 0;

InitPic();

while(1){
SetDigit(a,b,c,d,e);
count++;
if(count>150){
count = 0;
a++;
b++;
c++;
d++;
e++;
if(a>10){a = 0;}
if(b>10){b = 0;}
if(c>10){c = 0;}
if(d>10){d = 0;}
if(e>7){e = 0;}
}
}
}
 実際の動きはこんな感じです。[広告] VPS

 問題なく動作しましたので、次のステップに進もうと思います。

PIC Writerを改良する

 最近は、Raspberry Pi、Arduinoなどのボードコンピュータ、マイコン基板がその扱いやすさから広く普及しているような気がします。電子工作も楽で取っ付き易いですね。私自身もこの1、2年はRaspberry Piで遊んでいます。

 それ以前はMicrochip社のPICマイコンで遊んでいた時期がありました。PICマイコンは部品が数百円程度と安く、電子工作に十分過ぎる機能を持っているので個人的に好きです。
 その頃(6、7年前?)購入したものと思いますが、28pinのPIC16F873Aをたまたま見つけ、購入したけど使っていないことに気付きました。早速PIC16F873Aを何かに使えないかなと部品類を物色していると、「4桁の7セグ」と「温湿度、気圧センサ」があったので、これらを制御してやろうと思いました。

 PICにプログラムを書き込むのは、昔々購入した「PICkit2」で、いまだに現役で使っていますが、簡易自作したWriter(ピンヘッダとICソケットを配線したもの)が、18pin用(PIC16F628A)だったので、28pin用(PIC16F873A)でも使えるように改良することにしました。

 PICkit2はパソコンからPICにプログラムを書き込むためのツールですが、図のように6pin(うち1~5の5pinを使用)をPICの各種信号端子に接続します。PICKit2_170205.png PIC16F628AとPIC16F873Aの信号端子は下図の通りでpin番号も異なるので、新規に28pin用(PIC16F873A)を簡易自作Writerを追加しました。628A_170205.png_873A_170205.pngPICkit2_signal_170205.png
 完成品はこんな感じです。PIC_writer_170205.png 従来のPIC16F628A用と同じ基板上にPIC16F873A用を入れることができました。安っぽいですが、これで十分でしょう・・?。

ご訪問者数

(Since 24 July, 2016)

タグクラウド


プロフィール

Dr.BobT

Author: Dr.BobT
興味のおもむくままに生涯考え続けるエンジニアでありたい。

月別アーカイブ

メールフォーム

名前:
メール:
件名:
本文: