PICプログラム初心者のための16F84A用プログラムの書き換え方法とエラー回避方法

このQ&Aのポイント
  • PICプログラム初心者のための16F84A用プログラムの書き換え方法とエラー回避方法を紹介します。
  • 初心者に向けたPICプログラムの書き換え方法やエラー回避方法について解説します。
  • 16F628用のPICプログラムを16F84A用に書き換えたい初心者の方へ、エラー回避方法をご紹介します。
回答を見る
  • ベストアンサー

初歩のPICプログラム

最近PICはじめたばかりの全くの初心者です。9番ピンのLEDが点滅を繰り返すという16F628用のプログラムがあります。 これを16F84A用に書き換えたいんですが29行目に「Symbol not previously defined (CMCON)」というエラーがでます。どうやら16F84にはCMCONがないからのようです。これをなんとか回避する方法はないんでしょうか。うまく動かない書き換えたプログラムを下におきます。 list p=16f84a w_temp      EQU 0x70 status_temp    EQU 0x71 CNT1         EQU 0x20 CNT2        EQU 0x21       ORG   0x000     goto   main      ORG   0x004     movwf  w_temp     movf  STATUS,W     movwf   status_temp ;ISR Code    movf     status_temp,w    movwf     STATUS    swapf     w_temp,f    swapf     w_temp,w        retfie main    bcf   STATUS,RP0    bcf   STATUS,RP1    clrf   INTCON    clrf   PORTA    movlw   0x07    movwf   CMCON ;ここでエラーがでる    bsf   STATUS,RP0    clrf   TRISA    clrf   TRISB    bcf    STATUS,RP0    clrf    PORTA    clrf    PORTB main_loop    bsf  PORTB,3    call  DLY_250    bcf   PORTB,3    call   DLY_250    goto  main_loop ;Dalay Routine DLY_250   ;250mS 以下省略 空白が文字化けして見にくくてすみません。

noname#62952
noname#62952

質問者が選んだベストアンサー

  • ベストアンサー
  • tadys
  • ベストアンサー率40% (856/2135)
回答No.1

16F84にはCMCONが無いので、この行とその一つ前の行は削除してもかまいません。

noname#62952
質問者

お礼

回答ありがとうございます。 とりあえずはエラーきえました。あとはうまくうごくかですが。

noname#62952
質問者

補足

やー、うまくいきました。感動です。

関連するQ&A

  • PICのアセンブラからC言語へ変換のアドバイスです

    C言語ならわたしはわかるのですが、アセンブラは理解できるレベルにありません。機会があればいつか挑戦したいです。話は変わりますが、 以下のアセンブラのソースでLEDの点滅まで出来ましたが、これをC言語で理解したいと思っています。翻訳できる方がいらっしゃればご協力のほどよろしくお願いします。また、そこまでは無理でもわかる範囲でアドバイスを戴けたらと思います。よろしくお願いします。 asmソースです。 list p=16f628a #include<p16f628a.inc> __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _LVP_OFF w_temp EQU 0x70 status_temp EQU 0x71 CNT1 EQU 0x20 CNT2 EQU 0x21 ORG 0x000 goto main ORG 0x004 movwf w_temp movf STATUS,w movwf status_temp ;ISR Codes movf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie main bcf STATUS,RP0 bcf STATUS,RP1 clrf INTCON clrf PORTA movlw 0x07 movwf CMCON bsf STATUS,RP0 bsf PCON,OSCF clrf TRISA clrf TRISB bcf STATUS,RP0 clrf PORTA clrf PORTB main_loop bsf PORTB,3 call DLY_250 bcf PORTB,3 call DLY_250 goto main_loop ;Delay Routine DLY_250 ; 250ms movlw d'250' movwf CNT1 DLP1;1ms movlw d'200' movwf CNT2 DLP2 nop nop decfsz CNT2,f goto DLP2 decfsz CNT1,f goto DLP1 return END

  • PICのSleepからの復帰に関して

    INTピンを使ってsleepから割り込み復帰したいのですが、 思ったとおり動いてくれません。 メインをSLEEPにし、割り込みが入ると割り込み側の プログラムを実行し、終わるとメインのSLEEPに もどってINTの割り込みに備えるようにしたいのです。 現段階では割り込みをするとSLEEPから割り込み には行くのですが、そのまま割り込み側のプログラムを 永遠に繰り返してしまいます。 list p=12f629 include p12f629.inc RELOOP1 equ 0x20 CT_DELAYNMS equ 0x21 PCLATH_TEMP equ 0x2a W_TEMP equ 0x2b STATUS_TEMP equ 0x2c stu equ 0x2d org 0x0 goto start org 0x4 ;レジスタの退避 movwf W_TEMP swapf STATUS,W clrf STATUS movwf STATUS_TEMP movf PCLATH,W movwf PCLATH_TEMP clrf PCLATH ;割り込み要因のチェック btfss INTCON, INTF goto INT_NEXT1 ;ここから割り込みプログラム 省略 INT_NEXT1 ;レジスタの復帰 movf PCLATH_TEMP,w movwf PCLATH swapf STATUS_TEMP,W movwf STATUS swapf W_TEMP,F swapf W_TEMP,W retfie ;初期設定 start: ;aLED単独の輝度 bcf STATUS, RP0 clrf INTCON clrf GPIO bsf STATUS, RP0 clrf OSCCAL clrf TRISIO bsf TRISIO,2 movlw B'01000101' movwf OPTION_REG bcf STATUS, RP0 ;割り込み許可する movlw B'11010000' movwf INTCON nop sleep nop goto $-3 end こんな感じのプログラムなのですが、INTピンからの割り込みと いうことでプリスケーラなどは使っていません。 データシートも読んだのですが今市理解ができていない状況です。 お願いします。

  • PICの条件分岐について

    お世話になります。PICについて質問があります。ボタンを押せば、PORTBのLEDに対する出力が変わるという物ですが、意図したようになりません。PORTに対する設定は間違っていないと思うのですが、チャタリングを考慮したプログラムになっており、上手く条件分岐してくれません。条件というのは、PORTAに入力があれば、25ms待機して再度PORTAを見に行きます。そのときにもPORTAに入力があれば、変数に格納した数値を一つずつ減らしていき、そのときに0であればPORTBを設定したとおりに出力するというものです。以下がソースですが、ここがおかしいということだけでも教えてくださると助かります。よろしくお願いします。 list p=16f628a #include<p16f628a.inc> __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _LVP_OFF SWI equ 0x21 SWI2 equ 0x22 CNT1 EQU 0x20 CNT2 EQU 0x21 ORG 0x000 goto main ORG 0x004 main bcf STATUS,RP0 bcf STATUS,RP1 clrf INTCON clrf PORTA movlw 0x07 movwf CMCON bsf STATUS,RP0 bsf PCON,OSCF clrf TRISB movlw 0x03 movwf TRISA bcf STATUS,RP0 clrf PORTA clrf PORTB clrf SWI main_loop btfss PORTA,1 goto flase_wait_routine goto trues_wait_routine flase_wait_routine goto main_loop trues_wait_routine call DLY_25 btfss PORTA,1 goto main_loop incf SWI,f movf SWI,W movwf SWI2 decfsz SWI2,f goto a_loop_1 bsf PORTB,0 bcf PORTB,1 bcf PORTB,2 bcf PORTB,3 goto main_loop a_loop_1 decfsz SWI2,f goto a_loop_2 bcf PORTB,0 bsf PORTB,1 bcf PORTB,2 bcf PORTB,3 goto main_loop a_loop_2 decfsz SWI2,f goto a_loop_3 bcf PORTB,0 bcf PORTB,1 bsf PORTB,2 bcf PORTB,3 goto main_loop a_loop_3 decfsz SWI2,f goto a_loop_4 bcf PORTB,0 bcf PORTB,1 bcf PORTB,2 bsf PORTB,3 clrf SWI goto main_loop a_loop_4 goto main_loop ;Delay Routine DLY_25 ; 25ms movlw d'25' movwf CNT1 DLP1;1ms movlw d'20' movwf CNT2 DLP2 nop nop decfsz CNT2,f goto DLP2 decfsz CNT1,f goto DLP1 return END

  • PICのスイッチのプログラムについて

    基本的な事なのですが、よろしくお願いします。 以下のアセンブラのソースでPICを作ってみました。プログラムを変えてみたり、回路を変えてみたりしましたが、改善されませんでした。回路の構成は、LED(仮に、A・Bとします)2個、スイッチ1個、PIC、抵抗器など・・・これを交互にスイッチのオンオフで切り替える。としています。現状の問題点は、スイッチ入力で、LEDAは光るときは綺麗に光りますし、消えるときは綺麗に消えます。問題は、LEDBのほうで、光るときに高速で点滅します。理由と対策が解りません。どなたか教えてください。よろしくお願いします。 list p=16f628a #include<p16f628a.inc> __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _LVP_OFF ORG 0x000 goto main ORG 0x004 main bcf STATUS,RP0 bcf STATUS,RP1 clrf INTCON clrf PORTA movlw 0x07 movwf CMCON bsf STATUS,RP0 bsf PCON,OSCF clrf TRISB movlw 0x03 movwf TRISA bcf STATUS,RP0 clrf PORTA clrf PORTB main_loop btfsc PORTA,0;この辺りがよくわかりません。 goto loop2 bsf PORTB,0 bcf PORTB,1 goto main_loop loop2 bcf PORTB,0 bsf PORTB,1 goto main_loop END

  • PIC16F84Aで入力があるとスタートするプログラム

    PIC16F84Aで、アセンブリ言語でプログラムをしています。 RA4を入力端子とし、入力があればプログラムがスタートするということをしたいんですけどうまくいきません。 私の作ったプログラムはこのようになっています。  listp=16f84A   include <p16f84A.inc>  __CONFIG _HS_OSC & _PWRTE_ON & _WDT_OFF tim1   EQU  0x20      org  0x00      NOP      GOTO start start      BSF  STATUS,RP0      MOVLW B'00010000'      MOVWF TRISA      CLRF TRISB      BCF  STATUS,RP0      MOVLW B'00010000'      MOVWF PORTA      CLRF  PORTB main      MOVLW  001h      MOVWF  tim1 timlp1  BTFSC  PORTA,5      CALL   playball      GOTO   main playball      MOVLW  B'00001111'      MOVWF  PORTA      MOVLW  B'11111111'      MOVWF  PORTB      RETURN 修正点などありましたら教えて下さい。

  • PIC、USART USART送信ができません

    下記のプログラムでUSART接続してPICマイコンからPCに送信しようとしています。 PICマイコンはP16F877 アプリにはTera Term というアプリケーションを使用しています。 このプログラムはUSARTの送信とステッピングモータを交互に動作させるプログラムです。 このプログラムを実行したところ、ステッピングモータが微小に動作したままとまってしまいました。 Tera Termにも文字は出力されませんでした。 そのため、1周目だけTXREGレジスタにデータを格納するところまでは出来ていると思います。 しかし、データ送信が行われないため、2週目以降はTSRレジスタがBUSY状態となりプログラムが進行しないのだと考えています。 以下のサイトを参考に模索しましたが、原因が分かりませんでした。 http://www.kimurass.co.jp/pic/0625p.htm http://www.picfun.com/pic19.html どのように対処したらよろしいでしょうか? 原因やアドバイスなど教えていただけたら幸いです。 ~~プログラム~~ list p=16F877 #include <p16F877.inc> __CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF& _LVP_OFF w_temp EQU 0x0C status_temp EQU 0x0D ;変数 cblock 020h CNT15mS ;15mSカウンタ CNT5mS ;5mSカウンタ CNT1mS ;1mSカウンタ CNT50uS ;50μSカウンタ USART_TEMP ;USARTのワークレジスタ POINT ;point of table BUFFER ;buffer endc ;*************************割り込み退避************************** ORG 0x000 goto MAIN ORG 0x004 movwf w_temp movf STATUS,w movwf status_temp movf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;************************************************************* MAIN ;-----------------------------設定---------------------------- ;BANK1 Setting bsf STATUS,RP0 clrf TRISA movlw B'11110000' clrf TRISB movlw B'01000000' movwf TRISC ;RXピンを入力に設定 movlw B'00100000' movwf TXSTA ;SET TX MODE movlw 0FH ;Set Baud Rate 19Kbps movwf SPBRG ;Set BRG ;BANK0 Setting bcf STATUS,RP0 clrf INTCON movlw 07H movwf ADCON1 ;------------------------------------------------------------ ;----------------------------初期化--------------------------- clrf PORTA clrf PORTB bcf STATUS,C bcf STATUS,Z ;------------------------------------------------------------ ;===========================MAIN_LOOP======================== MAIN_LOOP bsf STATUS,RP0 READY_CHECK btfss TXSTA,TRMT goto READY_CHECK bcf STATUS,RP0 movlw 'A' movwf TXREG call STEPPING_MOTTER goto MAIN_LOOP ;============================================================ ;================= STEPPING MOTORE ========================== STEPPING_MOTTER call wait1ms call wait1ms movlw B'00000001' movwf PORTB call wait1ms call wait1ms movlw B'00000010' movwf PORTB call wait1ms call wait1ms movlw B'00000100' movwf PORTB call wait1ms call wait1ms movlw B'00001000' movwf PORTB RETURN ;================= 15mS WAIT ================================ wait15ms MOVLW d'3' MOVWF CNT15mS wait15ms_loop CALL wait5ms DECFSZ CNT15mS,F GOTO wait15ms_loop RETURN ;================= 5mS WAIT ================================= wait5ms MOVLW d'100' MOVWF CNT5mS wait5ms_loop CALL wait50us DECFSZ CNT5mS,F GOTO wait5ms_loop RETURN ;================= 1mS WAIT ================================= wait1ms MOVLW d'20' MOVWF CNT1mS wait1ms_loop CALL wait50us DECFSZ CNT1mS,F GOTO wait1ms_loop RETURN ;================= 50μS WAIT ================================ wait50us ; 1サイクル(4クロック):0.2μS ; 50μS=0.2μS×250サイクル MOVLW d'82' ;1 MOVWF CNT50uS ;1 wait50us_loop DECFSZ CNT50uS,F ;1 GOTO wait50us_loop ;2 RETURN ;2+1 ;============================================================ ;------------------------------------------------------------ END

  • PICマイコンをアセンブラでAD変換をした時に、、

    現在PICマイコンの16f88を用いてアセンブラでAD変換の勉強をしています。とりあえずいろいろなサイトやデータシートを見てAD変換した結果をPORTBに出力させるテスト用のプログラムを完成させたのですが、AD変換の結果を格納するADRESLのデータをうまく読み込むことができませんでした。その時のプログラムは(結果は左詰め,X_Lは自分で定義した変数) BSF STATUS,RP0 MOVF ADRESL,W MOVWF X_L ;ADRESLの結果をX_Lに保存 BCF STATUS,RP0 MOVF X_L,W MOVWF PORTB こんな感じです。わざわざADRESLの結果をX_Lに保存しなくても直接出力することもできるんですが気にしないで下さい。で、このプログラムだとPORTBにつないだ全てのLEDが点灯します。 ところがプログラムを以下の様に書き変えたら見事にADRESLレジスタの中身が出力できました。何が起きたのでしょうか?バンクの切り替えの前にWレジスタをX_Lレジスタに書き込むのと、バンクを切り替えてからWレジスタをX_Lレジスタに書き込むのとでは結果が同じになると思うのですが、、、。 BSF STATUS,RP0 MOVF ADRESL,W BCF STATUS,RP0 MOVWF X_L MOVF X_L,W MOVWF PORTB

  • PIC16F88のアナログコンパレータ使用について

         LIST    P=PIC16F88 #INCLUDE<P16F88.INC> __CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF &                    _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF &                    _PWRTE_ON & _WDT_OFF & _HS_OSC __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF VAR1 EQU 0x20 VAR2 EQU 0x21 ORG 0 start      BCF       STATUS,RP1      BSF       STATUS,RP0   ;bank1へ移動      CLRF      TRISB       ;PORTBをすべて出力      MOVLW     0xff      MOVWF     TRISA       ;PORTAをすべて入力      MOVLW      x05        ;コンパレータ1つのみ使用      MOVWF     CMCON      BCF       STATUS,RP0   ;bank0へ移動      CLRW      MOVWF     PORTB      MOVLW     0xff      MOVWF     PORTA 18ピンのPIC16F88の内蔵アナログコンパレータ(RA1/AN1とVINRA2/AN2/CVREFが入力、C2OUTが出力の1つのみ利用する設定)を使用しPORTBからLEDへ出力し電圧の大小の判定を行いたく、上記のような設定でプログラムをつくりコンパイルは通ったのですが動作せず、 MPLABのデバッグにて確認したところ『MOVWF PORTA』の部分でPORTAのレジスタ値が0x00から変化しておりませんでした。 『BCF STATUS,RP0』まではレジスタ値は変化しており、 STATUSは0x1cでbank0、TRISAは0x3fで入力、ANSELはデフォルトで0x7fでアナログ入力 になっているのですが、何故PORTAが値を入れても変わらないのか原因が分かりません。 分かる方、ご教授頂けますと幸いです。 宜しくお願い致します。

  • PIC 初歩プログラムについて

    PICの初めてのプログラムを書いたのですがテキストのように動きません。 ORG 0 ; MAIN  BSF STATUS,RP0 MOVLW B'00000000' ;ポートB 出力 MOVWF TRISB ; MOVLW B'00001111' ;ポートA 0,1,2,3入力 MOVWF TRISA ; BCF STATUS,RP0 SW BTFSS PORTA,0 GOTO  LED1 BTFSS PORTA,1 GOTO LED2 GOTO SW LED1 MOVLW B'00000010' MOVWF PORTB GOTO SW LED2 MOVLW B'00000001' MOVWF PORTB GOTO SW END 入力SWを押していないときがHIです。したがって何もしなければSWのループになると思うのですが、LED2に行ってしまいます。BTFSC POARTA,1とすればSWループ状態ですがテキストとは違います。 何かおかしいのでしょうか?

  • PIC アセンブラ TMR0の使い方がいまいちわかりません。

    *文字数制限の為コメントや繰り返し処理プログラムの一部を省きました。解りにくくてすみません。ココに載せてくれとかあったらそっちに全部載せます。 目標としてはPICでデジタル時計を作りたいのですが、手始めに正確な1秒を作って7セグを0から9まで表示しそれを繰り返す。と言うものをやってみようと思いプログラムしましたがウンともスンとも言いません。 流れとしては 初期処理 ↓ TMR0割り込みが発生するまで無限ループ ↓ 割り込みが発生したら割り込み回数をカウントし(12,8MHzクロック、プリスケーラを256設定で1250回フラグをカウントすると1秒)1秒間分カウントが終わったら7セグの表示を切り替え無限ループに戻る どの数字まで表示したかは任意のレジスタに1を立てて判断する。PICはPIC16F628AなのでTMR1とかもあるんですが気分的にTMR0だけで時間を作ってみたかったのでTMR1とかは使ってません。で、3回くらいやり直してプログラムを作ったんですが全然動きません。 1、何処が悪いんでしょうか? 2、また、PIC16F628Aでは16番ピンがクロックの入力として使えますが その設定方法があってるかわかりません。 コンフィグ設定で OSCをHSにしてポートの設定でRA7を入力にしておけば良いんでしょうか?プログラム中の記述で合ってますでしょうか? 3,7セグをカウントアップするだけのプログラムなのに こんなに長くなる物なんですか? (プログラムが下手だから?アセンブラだから?) 4、1秒のカウント方法ですがプログラム中の記述で正確に1秒をカウントしてますか?(計算間違ってますでしょうか?) 以下、プログラムになります。 list p=pic16f628a include "p16f628a.inc" __CONFIG _LVP_OFF &_MCLRE_ON &_BODEN_OFF &_PWRTE_ON &_WDT_OFF &_HS_OSC time0 equ d'30' ;time4まで作る tcount equ d'43' count0 equ d'35' ;count7まで作る koko0 equ d'43' koko1 equ d'44' org 0 goto start org 4 goto wari start bcf intcon,gie movlw b'00000111' movwf cmcon bsf status,rp0 movlw b'00000111' movwf option_reg movlw b'10100000' movwf trisa clrf trisb bcf status,rp0 bcf status,z bcf intcon,t0if movlw b'00001000' movwf count0 ;この間に1から6の同じ処理が入ります。 movlw b'00000000' movwf count7 time movlw .30 movwf time0 bsf intcon,gie bsf intcon,t0ie clrf tmr0 roop btfsc tcount,0 call segout swapf count0,0 movwf portb swapf portb,0 movwf count0 ;この間に1から5が入ります swapf count6,0 movwf portb swapf portb,0 movwf count6 goto roop wari bcf intcon,t0ie bcf intcon,t0if incf time0,1 btfss status,z goto modori bcf status,z movlw .255 movwf time0 incf time1,1 bcf status,z goto modori bcf status,z movlw .255 movwf time0 movlw .255 movwf time1 incf time2,1 bcf status,z goto modori bcf status,z movlw .255 movwf time0 movlw .255 movwf time1 movlw .255 movwf time2 incf time3,1 bcf status,z goto modori bcf status,z movlw .255 movwf time0 movlw .255 movwf time1 movlw .255 movwf time2 movlw .255 movwf time3 incf time4,1 bcf status,z goto modori bcf status,z movlw .30 movwf time0 movlw b'00000001' movwf tcount modori bsf intcon,t0ie retfie segout clrf tcount btfss koko0,0 goto seg1 ;この中間にseg2からseg6が入ります。 btfss koko0,7 goto seg8 btfss koko1,0 goto seg9 nop goto seg0 seg1 bsfkoko0,0 movlw b'00000010' movwf count0 movlw b'00000100' movwf count1 movlw b'00000000' movwf count2 movlw b'00000000' movwf count3 movlw b'00000000' movwf count4 movlw b'00000000' movwf count5 movlw b'00000000' movwf count6 movlw b'00000000' movwf count7 nop return ;この中間にseg2からseg9が入ります seg0 clrf koko1 clf koko0 movlw b'00001000' movwf count0 movlw b'00000100' movwf count1 movlw b'00000010' movwf count2 movlw b'00000001' movwf count3 movlw b'10000000' movwf count4 movlw b'01000000' movwf count5 movlw b'00000000' movwf count6 movlw b'00000000' movwf count7 return end