x STM8S-Discovery ボード
x NOP (ノップ?)やループでタイミングを取らずにダイレクト
x 割り込みを止めないと少しジャムる
x arduinoUNOとくらべるとなんか遅い。
x ALレジスタが1個?
目的
GPIOのテスト
構成
windows 10 20H2
Arduino
1.8.13(Windows Store 1.8.42.0)
マクロ化とクロックの安定化
# define L_NUM 8
char l[L_NUM*3]; //max8 led
const char train_x[16][L_NUM*3] =
{//G0,R0,B0 G1,R1,B1 G2,R2,B2 G3,R3,B3 G4,R4,B4 G5,R5,B5 G6,R6,B6 G7,R7,B7
{ 2,32,32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //0
{ 0, 0, 0, 32, 2,32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //1
{ 0, 0, 0, 0, 0, 0, 32,32, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //2
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,32, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //3
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,32,32, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //4
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,32,32, 0, 0, 0, 0, 0, 0}, //5
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 2,32, 0, 0, 0}, //6
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,32, 2}, //7
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 2,32, 0, 0, 0}, //8
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,32,32, 0, 0, 0, 0, 0, 0}, //9
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,32,32, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //10
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,32, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //11
{ 0, 0, 0, 0, 0, 0, 32,32, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //12
{ 0, 0, 0, 32, 2,32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //13
{ 2,32,32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //14
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} //15
};
# define PD_ODR *(volatile uint8_t *)0x500F
// 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3
# define bit_off1() PD_ODR=1;PD_ODR=0;PD_ODR=0;PD_ODR=0;PD_ODR=0;PD_ODR=0;PD_ODR=0;PD_ODR=0;
// 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
# define bit_on1() PD_ODR=1;PD_ODR=1;PD_ODR=1;PD_ODR=1;PD_ODR=1;PD_ODR=1;PD_ODR=1;PD_ODR=0;
//RGB_LEDにデータをn回分送る
void ws_led()
{
char al;
disableInterrupts();
//num1で指定された分だけループする
for(char ii=0;ii<(L_NUM*3);ii++){
al=l[ii];
if( al & 0b10000000 ){bit_on1();/*ビットが1*/}else{bit_off1();/*ビットが0*/}
if( al & 0b01000000 ){bit_on1();/*ビットが1*/}else{bit_off1();/*ビットが0*/}
if( al & 0b00100000 ){bit_on1();/*ビットが1*/}else{bit_off1();/*ビットが0*/}
if( al & 0b00010000 ){bit_on1();/*ビットが1*/}else{bit_off1();/*ビットが0*/}
if( al & 0b00001000 ){bit_on1();/*ビットが1*/}else{bit_off1();/*ビットが0*/}
if( al & 0b00000100 ){bit_on1();/*ビットが1*/}else{bit_off1();/*ビットが0*/}
if( al & 0b00000010 ){bit_on1();/*ビットが1*/}else{bit_off1();/*ビットが0*/}
if( al & 0b00000001 ){bit_on1();/*ビットが1*/}else{bit_off1();/*ビットが0*/}
}//for
enableInterrupts();
}//ws_led
//RGB_LEDに0データをn回分送る
void ws_led_cl()
{
disableInterrupts();
//num1で指定された分だけループする
for(char ii=0;ii< (L_NUM*3) ;ii++){
bit_off1(); //ビットが0
bit_off1(); //ビットが0
bit_off1(); //ビットが0
bit_off1(); //ビットが0
bit_off1(); //ビットが0
bit_off1(); //ビットが0
bit_off1(); //ビットが0
bit_off1(); //ビットが0
}//for
enableInterrupts();
}//ws_led
//初期設定
void setup() {
//外部の水晶16Mhzにする クロック安定かの為
CLK_ClockSwitchConfig ( CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSE, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE );
//GPIOの初期化
pinMode(PD0, OUTPUT);
}//setup
//メインループ
void loop() {
//状態を1つ進める
for(char jj=0;jj<16;jj++){
//1ライン(8個送る)
for(char ii=0;ii<(3*L_NUM);ii++){
l[ii] = train_x[jj][ii];
}//for ii
//ws2812bへデータを送る
ws_led();
//0.2秒待つ
delay(200);
}//for jj
}//loop
改良前
# define L_NUM 8
char l[L_NUM*3]; //max8 led
const char train_x[16][3*8] =
{//G0,R0,B0 G1,R1,B1 G2,R2,B2 G3,R3,B3 G4,R4,B4 G5,R5,B5 G6,R6,B6 G7,R7,B7
{ 2,32,32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //0
{ 0, 0, 0, 32, 2,32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //1
{ 0, 0, 0, 0, 0, 0, 32,32, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //2
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,32, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //3
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,32,32, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //4
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,32,32, 0, 0, 0, 0, 0, 0}, //5
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 2,32, 0, 0, 0}, //6
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,32, 2}, //7
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 2,32, 0, 0, 0}, //8
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,32,32, 0, 0, 0, 0, 0, 0}, //9
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,32,32, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //10
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,32, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //11
{ 0, 0, 0, 0, 0, 0, 32,32, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //12
{ 0, 0, 0, 32, 2,32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //13
{ 2,32,32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //14
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} //15
};
# define PD_ODR *(volatile uint8_t *)0x500F
// 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3
void bit_off1(){
//0.3us 800khz
PD_ODR = 0b00000001; //1 0.125
PD_ODR = 0b00000000; //2 0.250
PD_ODR = 0b00000000; //3 0.375
PD_ODR = 0b00000000; //4
PD_ODR = 0b00000000; //5
PD_ODR = 0b00000000; //1
PD_ODR = 0b00000000; //2
PD_ODR = 0b00000000; //3
PD_ODR = 0b00000000; //4
//PD_ODR = 0b00000000; //5
}//bit_off1
// 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
void bit_on1(){
//1us 800khz
PD_ODR = 0b00000001; //1
PD_ODR = 0b00000001; //2
PD_ODR = 0b00000001; //3
PD_ODR = 0b00000001; //4
PD_ODR = 0b00000001; //5
PD_ODR = 0b00000001; //1
PD_ODR = 0b00000001; //2
PD_ODR = 0b00000000; //3 0.375
PD_ODR = 0b00000000; //4 0.250
PD_ODR = 0b00000000; //5 0.125
}//bit_on1
//RGB_LEDにデータをn回分送る
void ws_led()
{
disableInterrupts();
//num1で指定された分だけループする
for(char ii=0;ii<(L_NUM*3);ii++){
if( l[ii] & 0b10000000 ){
bit_on1(); //ビットが1
} else {
bit_off1(); //ビットが0
}//endif
if( l[ii] & 0b01000000 ){
bit_on1(); //ビットが1
} else {
bit_off1(); //ビットが0
}//endif
if( l[ii] & 0b00100000 ){
bit_on1(); //ビットが1
} else {
bit_off1(); //ビットが0
}//endif
if( l[ii] & 0b00010000 ){
bit_on1(); //ビットが1
} else {
bit_off1(); //ビットが0
}//endif
if( l[ii] & 0b00001000 ){
bit_on1(); //ビットが1
} else {
bit_off1(); //ビットが0
}//endif
if( l[ii] & 0b00000100 ){
bit_on1(); //ビットが1
} else {
bit_off1(); //ビットが0
}//endif
if( l[ii] & 0b00000010 ){
bit_on1(); //ビットが1
} else {
bit_off1(); //ビットが0
}//endif
if( l[ii] & 0b00000001 ){
bit_on1(); //ビットが1
} else {
bit_off1(); //ビットが0
}//endif
}//for
enableInterrupts();
}//ws_led
//RGB_LEDに0データをn回分送る
void ws_led_cl()
{
disableInterrupts();
//num1で指定された分だけループする
for(char ii=0;ii< (L_NUM*3) ;ii++){
bit_off1(); //ビットが0
bit_off1(); //ビットが0
bit_off1(); //ビットが0
bit_off1(); //ビットが0
bit_off1(); //ビットが0
bit_off1(); //ビットが0
bit_off1(); //ビットが0
bit_off1(); //ビットが0
}//for
enableInterrupts();
}//ws_led
void setup() {
//GPIOの初期化
pinMode(PD0, OUTPUT);
}//setup
void loop() {
for(char jj=0;jj<16;jj++){
for(char ii=0;ii<(3*8);ii++){
l[ii] = train_x[jj][ii];
}//for ii
//ws2812bへデータを送る
ws_led();
//0.2秒待つ
delay(200);
}//for jj
}//loop