
| /*************************************************** * File: saikoro_C05.c * Author: karappi * Created on 2026/06/18, 21:33 12f629 さいころ 2026.05.06(xc) TMR0割り込みでランダムぽく表示 度数をカウントして頻度を操作 GP3 MCLR Anode-->Kathode LED1 GP0-->GP1 LED2 GP1-->GP2 LED3 GP2-->GP4 LED4 GP0-->GP2 LED5 GP1-->GP4 LED6 GP1-->GP0 LED7 GP2-->GP1 LEDの配置 R7 R1 R4 R2 R6 R3 R5 点灯パターン O:on X:off SEVEN_以降はデバッグ用 ONE_ TWO_ THREE_ FOUR_ X X X O X O O O X O X X X X X O X X X X X X O X O X O O FIVE_ SIX_ O O O O X O X O X O O O O O サイコロ目のパターン 一 LED_R2 二 LED_R1,LED_R3 三 LED_R1,LED_R2,LED_R3 四 LED_R!,LED_R5,LED_R3,LED_R7 五 LED_R!,LED_R5,LED_R3,LED_R7,LED_R2 六 ED_R1,LED_R3,LED_R4,LED_R5,LED_R6,LED_R7 ***************************************************/ #include<stdio.h> #include <xc.h> //#include <stdlib.h> #include <pic12f629.h> #define _XTAL_FREQ 40000000 //内部clock 4MHz for delay macro //config 1 #pragma config WDTE=OFF //Watchdog Timer off #pragma config PWRTE=ON //Power up timer on(スイッチを入れた直後電源が安定するまで待つ) #pragma config MCLRE=OFF //MCLR PIN off (ハードウェアリセットのピンの用途を無しにしてdigital pinとして使えるようにする) #pragma config CP=OFF //CODE PROTECT OFF プログラムの読み出しのプロテクトoff #pragma config CPD=OFF //Data Protect OFF データ領域の読み出しのプロテクトoff #pragma config BOREN=ON // Brownout on (もし電源が不安定のとき一時停止する) #pragma config FOSC=INTRCIO //Oscillator selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)) unsigned char dice; //サイコロの目 タイマー割り込みで変わる //unsigned char dosu[]={0,0,0,0,0,0}; static unsigned char dosu[6]; //サイコロの目の度数の記録 /******************************* タイマー割り込み *******************************/ void __interrupt() ISR(void){ if(TMR0IE){ dice++; if(dice > 6) dice=1; INTCONbits.T0IF=0;//TMR0オーバーフラグクリア } } /************************************* LED n ON モジュール群 *************************************/ /*** led on timer ***/ void ledontimer(unsigned char lonc){ unsigned char i,j; for(i=1;i<=lonc;i++){ for(j=1;j<=lonc;j++){} } GPIO=0; //LED OFF } /*** led R1 on GP0 -->GP1 ***/ void led_r1_on(unsigned char lonc){ TRISIO=0xfc; //GP0,GP1 OUT GPIO=0x01; //LED R1 ON ledontimer(lonc); //led on timer } /*** led R2 on GP1 -->GP2 ***/ void led_r2_on(unsigned char lonc){ TRISIO=0xf9; //GP1,GP2 OUT GPIO=0x02; //LED R2 ON ledontimer(lonc); //led on timer } /*** led R3 on GP2 -->GP4 ***/ void led_r3_on(unsigned char lonc){ TRISIO=0xeb; //GP2,GP4 OUT GPIO=0x04; //LED R3 ON ledontimer(lonc); //led on timer } /*** led R4 on GP0 -->GP2 ***/ void led_r4_on(unsigned char lonc){ TRISIO=0xfa; //GP0,GP2 OUT GPIO=0x01; //LED R4 ON ledontimer(lonc); //led on timer } /*** led R5 on GP1 -->GP4 ***/ void led_r5_on(unsigned char lonc){ TRISIO=0xed; //G1,GP4 OUT GPIO=0x02; //LED R5 ON ledontimer(lonc); //led on timer } /*** led R6 on GP1 -->GP0 ***/ void led_r6_on(unsigned char lonc){ TRISIO=0xfc; //G1,GP0 OUT GPIO=0x02; //LED R6 ON ledontimer(lonc); //led on timer } /*** led R7 on GP2 -->GP1 ***/ void led_r7_on(unsigned char lonc){ TRISIO=0xf9; //G2,GP1 OUT GPIO=0x04; //LED R6 ON ledontimer(lonc); //led on timer } /********************************************* サイコロの目表示 入力 MEON サイコロの目の点灯時間 SNUM 表示したいサイコロの目の番号1〜6 **********************************************/ void saikoro_d(unsigned char snum,unsigned char meon){ unsigned char i,j; for(i=0;i<=meon/2;i++){ for(j=0;j<=meon;j++){ switch(snum){ case 1: led_r2_on(12); //引数は点灯タイマカウンタ break; case 2: led_r1_on(8); //引数は点灯タイマカウンタ led_r3_on(8); //引数は点灯タイマカウンタ break; case 3: led_r1_on(7); //引数は点灯タイマカウンタ led_r2_on(7); //引数は点灯タイマカウン タ led_r3_on(7); //引数は点灯タイマカウンタ break; case 4: led_r1_on(5); //引数は点灯タイマカウンタ led_r3_on(5); //引数は点灯タイマカウンタ led_r7_on(5); //引数は点灯タイマカウンタ led_r5_on(5); //引数は点灯タイマカウン タ break; case 5: led_r1_on(4); //引数は点灯タイマカウンタ led_r2_on(4); //引数は点灯タイマカウン タ led_r3_on(4); //引数は点灯タイマカウンタ led_r7_on(4); //引数は点灯タイマカウンタ led_r5_on(4); //引数は点灯タイマカウン タ break; case 6: led_r1_on(3); //引数は点灯タイマカウンタ led_r3_on(3); //引数は点灯タイマカウンタ led_r7_on(3); //引数は点灯タイマカウンタ led_r5_on(3); //引数は点灯タイマカウンタ led_r4_on(3); //引数は点灯タイマカウン タ led_r6_on(3); //引数は点灯タイマカウン タ break; default: break; } } } GPIO=0; } /*********************************** サイコロを振る 入力 無し 出力 unsingend char snum 実際はタイマー割り込みが毎度更新するdiceをsnumとし出力する 但、目の出現頻度の差が4を超えたら最小頻度の目を出力 diceが最大頻度の目と同じでかつ出現頻度差が2を超えていたら __delay_(17)でウェイトしてから再度diceをsnumとして出力 ************************************/ unsigned char snumgen(){ unsigned char i,max,min; unsigned char min_i,max_i; //最小頻度、最大頻度の目のindex unsigned char snum; //サイコロの目 min=255; max=0; for(i=0;i<=5;i++){ if(dosu[i]<min){ min=dosu[i]; min_i=i; //最小頻度の目記憶 } if(dosu[i]>max){ max=dosu[i]; max_i=i; //最大頻度の目記憶 } } snum=dice; //サイコロを振る if(max-min>4){//もし頻度差が4を超えていたら snum=min_i+1; //目は最小頻度の目にする }else if((snum==max_i+1) && (max-min>2)){//最大頻度の目と同じで頻度差が2を __delay_ms(17); //越えていたらちょっと待って snum=dice; //振りなおす } dosu[snum-1]++;//頻度更新 if(dosu[snum-1]==0){//オーバーフロー dosu[0]=dosu[1]=dosu[2]=dosu[3]=dosu[4]=dosu[5]=0;//オールクリア& amp; amp; amp; amp; amp; amp; amp; amp; nbsp; } return snum; } /****************************** サイコロ メイン関数 *****************************/ int main(void){ unsigned char lonc; //LED on counter unsigned char lpc; //loop counter unsigned char snum ; //さいころの表示num unsigned char meon ; //さいころの目ONのループカウンタ初期値 while(1){ INTCONbits.GIE=0; //割り込み禁止 INTCONbits.PEIE=0; //割り込み禁止 TRISIO=0x08; //PORT 0,1,2,4,5=OUT, PORT3=INPUT/MCRLE OPTION_REG=0; //Option regi 0 IOC=0x08; //GPIO3でsleepからWakeupするための割り込み設定 INTCON=0x08; //GPIE on (GPIO 割り込み許可) GPIO=0; SLEEP(); //GPIO3(MCRL)がLOWになるまで冬眠 TRISIO=0x08; //PORT 0,1,2,4,5=OUT, PORT3=INPUT/MCRLE OPTION_REG=0x05; //Option regi 内部クロック プリスケーラ64 TMR0=0; INTCON=0; //余計な割り込みフラグは消しておく INTCONbits.T0IE=1; //TMR0割り込み許可 INTCONbits.GIE=1; //全体割り込み許可 __delay_ms(40); //ここでワンクッションおいてタクトスイッチ //チャタリングを避ける while(GPIO3==0){}//GPIO3が押されている間はここでループ //GPIO3はプルアップなのでonのとき==0 & nbsp; lonc=0x30; while(GPIO3 !=0){ //GPIO3がonになるまでバラバラledを点滅 //GPIO3はプルアップなのでonのとき==0 led_r1_on(lonc); __delay_ms(1); led_r2_on(lonc); __delay_ms(1); led_r3_on(lonc); __delay_ms(1); led_r4_on(lonc); __delay_ms(1); led_r5_on(lonc); __delay_ms(1); led_r6_on(lonc); __delay_ms(1); led_r7_on(lonc); __delay_ms(1); } //タクトスイッチON TMR0 取り出し サイコロの最終の目決定 while(GPIO3 ==0){} //タクトスイッチ離すまで何もしない meon=0x10; //サイコロの目on時間初期値 lpc=0x1e; // ループカウンタセット while(lpc-- != 0){ saikoro_d(lpc % 6 +1,meon); //サイコロの目表示 } //目をブリンクして終了する meon=0x20; snum=snumgen();//サイコロをふる saikoro_d(snum,meon); __delay_ms(30); saikoro_d(snum,meon); __delay_ms(30); saikoro_d(snum,meon); __delay_ms(30); meon=0x40; saikoro_d(snum,meon); } return 0; } |