トピック関連記事
48時間以内の記事は で表示されます
動作しなくなりました。
皆さんこんばんは。
PIC/ですが、今日秋月から16F1827が届きました。 16F627Aより安かったです。
これから、頑張りたいと思います。
それで、いきなりなんですが、以前、動作したはずの以下のプログラムですが、
まったく動作しません。
2日間見ましたが、ダメでした。
どうしてなんでしょうか??
すみませんが見ていただけますか。
宜しくお願いします。
動作
可変抵抗 RA0に接続
RB3に接続のLEDが可変抵抗により調光する。
/*PWM機能によりRB3のLEDで滑らかに調光。可変抵抗で制御 RA0可変抵抗接続*/
// PIC16F88 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1
#pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTRC oscillator; port I/O function on both RA6/OSC2/CLKO pin and RA7/OSC1/CLKI pin)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is MCLR)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EE Memory Code Protection bit (Code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off)
#pragma config CCPMX = RB3 // CCP1 Pin Selection bit (CCP1 function on RB3)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
// CONFIG2
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor enabled)
#pragma config IESO = OFF // Internal External Switchover bit (Internal External Switchover mode enabled)
#include <xc.h>
// クロック周波数指定
// (__delay_ms()関数が必要としているため)
#define _XTAL_FREQ 4000000
// プロトタイプ宣言
void InitPWM(void);
void InitTimer2(void);
unsigned int adconv(void);
// メイン関数
void main(void) {
OSCCON = 0b0110101; //クロック周波数を4MHzに設定
PORTA = 0xFF;
PORTB = 0xFF;
ANSEL = 0b00000011; //RA0をアナログピンに設定
// 入出力設定
TRISA = 0b00000011; // RA0(AN0)はアナログで読み取りピン(入力)
TRISB = 0x00; //全て出力端子
// ADコンバータ設定
ADCON0 = 0b00000001; // RA0をADコンバータピンにし、ADコンバータ機能をEbableに
ADCON1 = 0b10000000; // 結果数値は右寄せ、ADコンバータクロックはFOSC/2、基準電圧はVDD
//変数宣言
unsigned int num;
// PWMモード設定関数の呼び出し
InitPWM();
// タイマ2設定関数の呼び出し
InitTimer2();
while (1) {
// アナログ値の変換と読込み処理関数 呼び出し
num = adconv(); //RA0から電圧を読み込んだ値をtempをnumに代入
CCPR1L = num / 4; // 4で割って上位8ビットを取り出しアナログ値からのデータでデューティ値を設定
__delay_ms(10);
}
}
// アナログ値の変換と読込み処理関数
unsigned int adconv() {
unsigned int temp;
ADCON0bits.GO_DONE = 1; //AD変換開始
while (ADCON0bits.GO_DONE); //変換完了待ち
temp = ADRESH; //
temp = (temp << 8) + ADRESL; //RA0で読み込んだ値をtempに代入
return temp; //読み込んだtempをnumに返す
}
// PWMモード設定関数
void InitPWM(void) {
// RB3端子を出力端子に設定
TRISBbits.TRISB3 = 0;
// CCPのモードをPWMモードに設定
CCP1CONbits.CCP1M3 = 1;
CCP1CONbits.CCP1M2 = 1;
CCP1CONbits.CCP1M1 = 0;
CCP1CONbits.CCP1M0 = 0;
// 周期を255μ秒に設定(PR2 + 1μ秒)×1/(動作処理速度÷4)
PR2 = 0b11111111;//PR2レジスタ8bit0~255
// デューティーサイクルを0msで初期化
CCPR1L = 0;
CCP1CONbits.CCP1X = 0;
CCP1CONbits.CCP1Y = 0;
}
// タイマ2設定関数
void InitTimer2(void) {
// プリスケーラ値を1に設定
T2CONbits.T2CKPS1 = 0;
T2CONbits.T2CKPS0 = 0;
// TMR2レジスタをクリア
TMR2 = 0;
// タイマ2起動
T2CONbits.TMR2ON = 1;
}
PIC/ですが、今日秋月から16F1827が届きました。 16F627Aより安かったです。
これから、頑張りたいと思います。
それで、いきなりなんですが、以前、動作したはずの以下のプログラムですが、
まったく動作しません。
2日間見ましたが、ダメでした。
どうしてなんでしょうか??
すみませんが見ていただけますか。
宜しくお願いします。
動作
可変抵抗 RA0に接続
RB3に接続のLEDが可変抵抗により調光する。
/*PWM機能によりRB3のLEDで滑らかに調光。可変抵抗で制御 RA0可変抵抗接続*/
// PIC16F88 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1
#pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTRC oscillator; port I/O function on both RA6/OSC2/CLKO pin and RA7/OSC1/CLKI pin)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is MCLR)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EE Memory Code Protection bit (Code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off)
#pragma config CCPMX = RB3 // CCP1 Pin Selection bit (CCP1 function on RB3)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
// CONFIG2
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor enabled)
#pragma config IESO = OFF // Internal External Switchover bit (Internal External Switchover mode enabled)
#include <xc.h>
// クロック周波数指定
// (__delay_ms()関数が必要としているため)
#define _XTAL_FREQ 4000000
// プロトタイプ宣言
void InitPWM(void);
void InitTimer2(void);
unsigned int adconv(void);
// メイン関数
void main(void) {
OSCCON = 0b0110101; //クロック周波数を4MHzに設定
PORTA = 0xFF;
PORTB = 0xFF;
ANSEL = 0b00000011; //RA0をアナログピンに設定
// 入出力設定
TRISA = 0b00000011; // RA0(AN0)はアナログで読み取りピン(入力)
TRISB = 0x00; //全て出力端子
// ADコンバータ設定
ADCON0 = 0b00000001; // RA0をADコンバータピンにし、ADコンバータ機能をEbableに
ADCON1 = 0b10000000; // 結果数値は右寄せ、ADコンバータクロックはFOSC/2、基準電圧はVDD
//変数宣言
unsigned int num;
// PWMモード設定関数の呼び出し
InitPWM();
// タイマ2設定関数の呼び出し
InitTimer2();
while (1) {
// アナログ値の変換と読込み処理関数 呼び出し
num = adconv(); //RA0から電圧を読み込んだ値をtempをnumに代入
CCPR1L = num / 4; // 4で割って上位8ビットを取り出しアナログ値からのデータでデューティ値を設定
__delay_ms(10);
}
}
// アナログ値の変換と読込み処理関数
unsigned int adconv() {
unsigned int temp;
ADCON0bits.GO_DONE = 1; //AD変換開始
while (ADCON0bits.GO_DONE); //変換完了待ち
temp = ADRESH; //
temp = (temp << 8) + ADRESL; //RA0で読み込んだ値をtempに代入
return temp; //読み込んだtempをnumに返す
}
// PWMモード設定関数
void InitPWM(void) {
// RB3端子を出力端子に設定
TRISBbits.TRISB3 = 0;
// CCPのモードをPWMモードに設定
CCP1CONbits.CCP1M3 = 1;
CCP1CONbits.CCP1M2 = 1;
CCP1CONbits.CCP1M1 = 0;
CCP1CONbits.CCP1M0 = 0;
// 周期を255μ秒に設定(PR2 + 1μ秒)×1/(動作処理速度÷4)
PR2 = 0b11111111;//PR2レジスタ8bit0~255
// デューティーサイクルを0msで初期化
CCPR1L = 0;
CCP1CONbits.CCP1X = 0;
CCP1CONbits.CCP1Y = 0;
}
// タイマ2設定関数
void InitTimer2(void) {
// プリスケーラ値を1に設定
T2CONbits.T2CKPS1 = 0;
T2CONbits.T2CKPS0 = 0;
// TMR2レジスタをクリア
TMR2 = 0;
// タイマ2起動
T2CONbits.TMR2ON = 1;
}
Re: 動作しなくなりました。
TRさん,猛牛ロックさん,こんばんは。
猛牛ロックさん,前スレ,詳しい解説ありがとうございます。
いつもながら,勉強になります。
TRさん,頑張ってられますね。
細かい原因はわからないのですが,以前私も,PWMとAD変換の組み合わせで,はまりました。
私のプログラムがうまく行かなかった原因は,
http://mabo52.sakura.ne.jp/index.php?c=7-11&page=2
にも書きましたが,周辺機器割り込み(拡張割り込み?)を許可しないためでした。
多分うまく動いていた私のプログラム掲載します。
ただ,今,見返してみて,なんでこんなことしたのかと,
忘れていること多いです。
このプログラム,かない古い環境でのものなので,
手直ししないと動かないと思います。
//************************************
//16F88 HI-TECH C v.9.83
//RA0(AN0)の入力電圧をA/D変換
//AD変換後割り込みで、結果をLCD表示
//PWMに取り込んでステッピングモーターを無段階にコントロール
// 約1khz〜240Hz
// 2014−11−21〜
//************************************
#define _LEGACY_HEADERS
#include "pic.h"
#include "stdlib.h"
#include "lcd.h"
#define _XTAL_FREQ 8000000
__CONFIG(CCPRB3 & DEBUGDIS & LVPDIS & BOREN & MCLRDIS & PWRTEN & WDTDIS & INTIO);
unsigned int adconv(void);
void set_duty(unsigned int);
static void interrupt isr(void);
unsigned int tmp;
unsigned int temp1;
unsigned char temp2;
unsigned int dummy;
unsigned int i;
unsigned int cnt1;
char str[7];
void main(void){
//OSCCON = 0x60;// 内蔵OSC 4MHz
OSCCON = 0x50;// 内蔵OSC 2MHz
ADCS2 = 0;//AD変換のクロック選択
ADCS1 = 0;//001で2.0μs
ADCS0 = 1;//
//ADFM = 1;// AD変換結果は右詰めで格納
ADFM = 0;// AD変換結果は左詰めで格納
VCFG1 = 0;// 基準電圧はVddとVss
VCFG0 = 0;
ANSEL = 0b00000001;// RA0(AN0)はアナログ
TRISA = 0b00000001;// RA0(AN0)入力
TRISB = 0b00000000;// すべて出力
PORTA = 0b00000000;// すべてlow
PORTB = 0b00000000;// すべてlow
CCP1CON = 0b00001100; // PWMモードにする
T2CON = 0b00000111; // プリスケール16
set_duty(1);//デューティーの設定 DC1{CCPR1L・CCP1CON(5:4)}*Tosc(クロック)*プリスケラ-
// DC1*0.25usec*16=5 DC1=1.25
lcd_init();//SD1602の初期化4
ADIF = 0;//AD割り込みフラグクリアー
ADIE = 1;//AD割り込み許可
PEIE=1;//拡張割り込み許可(これがないとAD変換後の割り込みができない)
GIE= 1;//割り込み全体の許可
while (1){
tmp = adconv();//AD変換 結果をtmpに格納
//if(tmp>60){PR2=tmp;}//PWMの設定 PR2 = (PWM周期 / 4 * Tosc * TMR2プリスケール値) - 1
//if(tmp<60){PR2=60;} //PR2に60〜255を代入
if(tmp>=30){PR2=tmp;}//PWMの設定 PR2 = (PWM周期 / 4 * Tosc * TMR2プリスケール値) - 1
if(tmp<30){PR2=30;} //PR2に60〜255を代入
}
}
unsigned int adconv(void){
CHS2 = 0;//AD変換ポート設定
CHS1 = 0;//000でRA0
CHS0 = 0;//
ADON = 1;//AD変換ON
__delay_us(20);//アクイジション時間 20us
GODONE = 1;//AD変換開始
while(GODONE);//変換完了待ち
return (ADRESH) ;//変換結果を返す
}
void set_duty(unsigned int duty){//DUTYの設定
unsigned int temp1 ;
unsigned char temp2 ;
temp1 = duty ;
temp1 >>= 2 ;
temp2 = temp1 & 0xff;
CCPR1L = temp2 ;
temp1 = duty ;
temp1 <<= 4 ;
temp2 = temp1 | 0x0c ;
CCP1CON = temp2 ;
}
static void interrupt isr(void){
if(ADIF == 1){//AD変換後の割り込みでLCDに表示
itoa(str,tmp,10);//
lcd_clear();//表示クリア
lcd_goto(0);//カーソルを0行目の先頭に移動する
lcd_puts("PR2=");
lcd_puts(str);
__delay_ms(10);//10msの時間待ち
ADIF = 0;
}
}
猛牛ロックさん,前スレ,詳しい解説ありがとうございます。
いつもながら,勉強になります。
TRさん,頑張ってられますね。
細かい原因はわからないのですが,以前私も,PWMとAD変換の組み合わせで,はまりました。
私のプログラムがうまく行かなかった原因は,
http://mabo52.sakura.ne.jp/index.php?c=7-11&page=2
にも書きましたが,周辺機器割り込み(拡張割り込み?)を許可しないためでした。
多分うまく動いていた私のプログラム掲載します。
ただ,今,見返してみて,なんでこんなことしたのかと,
忘れていること多いです。
このプログラム,かない古い環境でのものなので,
手直ししないと動かないと思います。
//************************************
//16F88 HI-TECH C v.9.83
//RA0(AN0)の入力電圧をA/D変換
//AD変換後割り込みで、結果をLCD表示
//PWMに取り込んでステッピングモーターを無段階にコントロール
// 約1khz〜240Hz
// 2014−11−21〜
//************************************
#define _LEGACY_HEADERS
#include "pic.h"
#include "stdlib.h"
#include "lcd.h"
#define _XTAL_FREQ 8000000
__CONFIG(CCPRB3 & DEBUGDIS & LVPDIS & BOREN & MCLRDIS & PWRTEN & WDTDIS & INTIO);
unsigned int adconv(void);
void set_duty(unsigned int);
static void interrupt isr(void);
unsigned int tmp;
unsigned int temp1;
unsigned char temp2;
unsigned int dummy;
unsigned int i;
unsigned int cnt1;
char str[7];
void main(void){
//OSCCON = 0x60;// 内蔵OSC 4MHz
OSCCON = 0x50;// 内蔵OSC 2MHz
ADCS2 = 0;//AD変換のクロック選択
ADCS1 = 0;//001で2.0μs
ADCS0 = 1;//
//ADFM = 1;// AD変換結果は右詰めで格納
ADFM = 0;// AD変換結果は左詰めで格納
VCFG1 = 0;// 基準電圧はVddとVss
VCFG0 = 0;
ANSEL = 0b00000001;// RA0(AN0)はアナログ
TRISA = 0b00000001;// RA0(AN0)入力
TRISB = 0b00000000;// すべて出力
PORTA = 0b00000000;// すべてlow
PORTB = 0b00000000;// すべてlow
CCP1CON = 0b00001100; // PWMモードにする
T2CON = 0b00000111; // プリスケール16
set_duty(1);//デューティーの設定 DC1{CCPR1L・CCP1CON(5:4)}*Tosc(クロック)*プリスケラ-
// DC1*0.25usec*16=5 DC1=1.25
lcd_init();//SD1602の初期化4
ADIF = 0;//AD割り込みフラグクリアー
ADIE = 1;//AD割り込み許可
PEIE=1;//拡張割り込み許可(これがないとAD変換後の割り込みができない)
GIE= 1;//割り込み全体の許可
while (1){
tmp = adconv();//AD変換 結果をtmpに格納
//if(tmp>60){PR2=tmp;}//PWMの設定 PR2 = (PWM周期 / 4 * Tosc * TMR2プリスケール値) - 1
//if(tmp<60){PR2=60;} //PR2に60〜255を代入
if(tmp>=30){PR2=tmp;}//PWMの設定 PR2 = (PWM周期 / 4 * Tosc * TMR2プリスケール値) - 1
if(tmp<30){PR2=30;} //PR2に60〜255を代入
}
}
unsigned int adconv(void){
CHS2 = 0;//AD変換ポート設定
CHS1 = 0;//000でRA0
CHS0 = 0;//
ADON = 1;//AD変換ON
__delay_us(20);//アクイジション時間 20us
GODONE = 1;//AD変換開始
while(GODONE);//変換完了待ち
return (ADRESH) ;//変換結果を返す
}
void set_duty(unsigned int duty){//DUTYの設定
unsigned int temp1 ;
unsigned char temp2 ;
temp1 = duty ;
temp1 >>= 2 ;
temp2 = temp1 & 0xff;
CCPR1L = temp2 ;
temp1 = duty ;
temp1 <<= 4 ;
temp2 = temp1 | 0x0c ;
CCP1CON = temp2 ;
}
static void interrupt isr(void){
if(ADIF == 1){//AD変換後の割り込みでLCDに表示
itoa(str,tmp,10);//
lcd_clear();//表示クリア
lcd_goto(0);//カーソルを0行目の先頭に移動する
lcd_puts("PR2=");
lcd_puts(str);
__delay_ms(10);//10msの時間待ち
ADIF = 0;
}
}
mabo 2018/12/08(Sat) 21:58 No.1315