永发信息网

PIC单片机编程的问题 刚学 不太懂

答案:4  悬赏:80  手机版
解决时间 2021-04-01 17:29
PIC单片机编程的问题 刚学 不太懂
最佳答案

; 实例 供参考 可以直接仿真,多看看实例  会有帮助的。
; *********************************************************************
; *      GPIO0-V  GPIO1-I  GPIO2-LED1  GPIO4-LED2  GPIO5-OUT          *
; *      GPIO3-10K                                                    *
; *********************************************************************
          LIST P=12F675
          INCLUDE "P12F675.INC"  ; 包含MPLAB预定义的头文件
          __CONFIG(0x3FC4)       ; 11 ---1 1100 1000  设定配置字信息
                                 ; _CPD_OFF & _CP_OFF & _BODEN_ON & _MCLRE_OFF 
                                 ; 关代码-数据保护,    掉电复位使能,内部复位,
                                 ; _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
                                 ; 上电复位延时使能,关看门狗,内部振荡无时钟输出
; *************************************************
; * 寄存器定义及RAM分配                           *
; *************************************************
          ERRORLEVEL -302           ; 编译输出结果中不要显示message
          cblock 0x20               ; 通用变量定义从该地址开始
          W_TEMP                    ; 中断服务程序用来临时保存W和STATUS 
          STATUS_TEMP
          FLAGS                     ; 程序要使用的状态标志寄存器
          PWM_HIGH:2                ; 新的PWM高电平时间,保留两个字节
          PWM_LOW:2                 ; 新的PWM低电平时间,保留两个字节
          PWM_HIGH_CURRENT:2        ; 当前PWM的高电平时间锁存
          PWM_LOW_CURRENT:2         ; 当前的PWM低电平时间锁存
          COUNTER                   ; AD采样次数计数
          adsum:2                   ; 16位的AD累加结果,用于平均运算,两个字节
          temp:2                    ; 用于数学运算的临时变量,两个字节
          endc                      ; 结束cblock变量定义
          count   EQU   38H
          result  EQU   39H
;************************************************
;I/O引脚初始化                                  *
;以及 A/D 初始化                                *
;************************************************
;GP0 = 模拟电压输入
;GP1 = 没有使用
;GP2 = 没有使用
;GP3 = 只能作为输入,连接10K下拉电阻到地,ICSP烧录会使用该引脚
;GP4 = PWM1  输出引脚
;GP5 = PWM2  输出引脚
          ; / *** *** *** *** *** /   代换定义
#define PWM_OUTPUT     GPIO,2  ; GPIO,4
#define LOAD_PWM       FLAGS,0
#define CALCULATE_AD   FLAGS,1
#define PWM_TICKS      .1024   ; PWM时间片的个数,如果PWM的分辨率是10位,
#define TEST_PWM_HIGH  .512    ; 用于测试的50%占空比,高电平时间等于PWM时间片的一半
#define TEST_PWM_LOW   PWM_TICKS-TEST_PWM_HIGH  ; 低电平时间等于PWM时间片减高电平时间
#define ISR_DELAY      .16     ; 从Timer1溢出到进入中断重新装载Timer1值的延时,
                               ; 可通过软件模拟来确定该值
#define NUM_AD_SAMPLES .16     ; AD采样次数
#define AD_TIME_INTERVAL .10   ; 0xFF - (.245)   AD时间间隔,10个cycle的循环
          ; / *** *** *** *** *** /   定义双字节常数减变量的宏
          ; const_input - input = output
sub_const_16 macro const_input, input, output
          movlw   low const_input   ; W = low 双字节常数   L
          movwf   temp
          movlw   high const_input  ; W = high 双字节常数 H
          movwf   temp+1
          movf    input,w           ; W = input
          subwf   temp,w            ; W = temp - W 
          movwf   output            ; output = W
          movf    input+1,w         ; W = input+1
          btfss   STATUS,C          ; C = 1 ->
          incf    input+1,w         ; W = input+1 + 1
          subwf   temp+1,w          ; W = temp+1 - W 
          movwf   output+1          ; output+1 = W
          endm
          ; / *** *** *** *** *** /   定义双字节常数加变量的宏
          ; const_input + input = output
add_const_16 macro const_input, input, output
          movlw   low const_input   ; W = low 双字节常数   L
          movwf   temp
          movlw   high const_input  ; W = high 双字节常数 H
          movwf   temp+1
          movf    input,w           ; W = input
          addwf   temp,w            ; W = temp + W 
          movwf   output            ; output = W
          movf    input+1,w         ; W = input+1
          btfsc   STATUS,C          ; C = 0 ->
          incf    input+1,w         ; W = input+1 + 1
          addwf   temp+1,w          ; W = temp+1 + W 
          movwf   output+1          ; output+1 = W
          endm
          ; / *** *** *** *** *** /   程序开始
          ; / *** *** *** *** *** /
          org     0000H             ; 芯片复位入口地址0x00
          goto    MAIN000           ; 主程序
          ; / *** *** *** *** *** /   中断服务子程序
          ; / *** *** *** *** *** /
          ; INTCON,T0IF---TMR0  溢出    INTCON,INTF---GP2/INT外部中断
          ; INTCON,GPIF---GP5-GP0 引脚电平发生了变化
          ; PIR1,EEIF---EEPROM 写操作完成  PIR1,ADIF---A/D 转换完成
          ; PIR1,CMIF---比较器输入已改变   PIR1,TMR1IF---TMR1  溢出
          org     0004h             ; 中断入口地址0x0004
INTCON00  movwf   W_TEMP            ; W_TEMP = W  保存
          swapf   STATUS,W          ; STATUS_TEMP = STATUS
          movwf   STATUS_TEMP
          bcf     STATUS,RP0        ; 选择Bank 0

INTCON02  movlw   b'00000100'       ; 把W的第四位置高,其他都是零
          xorwf   GPIO,F            ; 和GPIO异或,也就是把PWM输出脚的电平反转
                                    ; 判断中断种类
INTCON03  bcf     PIR1,TMR1IF       ; 清 T1 中断标志 Timer1 中断
          movlw   HIGH 3CAFH        ; Timer1 = 50 mS  C350H
          movwf   TMR1H             ; FFFFH - C350H = 3CAFH
          movlw   LOW 3CAFH
          movwf   TMR1L
          bsf     CALCULATE_AD      ; 置位 A/D 转换标志
          bsf     LOAD_PWM          ; 置位 PWM 标志
INTCON08  swapf   STATUS_TEMP,W     ; 恢复STATUS寄存器
          movwf   STATUS
          swapf   W_TEMP,F          ; 恢复W寄存器
          swapf   W_TEMP,W
          retfie                    ; 从中断返回
          ; / *** *** *** *** *** /   主程序
          ; / *** *** *** *** *** /
MAIN000   clrf    GPIO              ; 初始化GPIO端口寄存器为零
          bsf     STATUS, RP0       ; 选择Bank 1
          call    0x3FF             ; 读内部振荡出厂校准字,返回值在W寄存器内
          movwf   OSCCAL            ; 内部振荡器校准
          movlw   b'11000011'       ; 设置GP<0>为输入,所有其他口为输出
          movwf   TRISIO         
          movlw   01h               ; 使能Timer1中断 01h
          movwf   PIE1
          movlw   b'00010001'       ; AD采用FOSC/8 时钟,GP2是模拟口,
          movwf   ANSEL             ; 其他口为数字IO
          movlw   b'00001000'       ; Timer0设置为使用内部指令周期,无预分频
          movwf   OPTION_REG
          bcf     STATUS, RP0       ; 选择Bank0
          movlw   b'10000001'       ; A/D是右对齐格式,Vdd为参考,GP0作为AD输入口
          movwf   ADCON0
          movlw   b'00000111'       ; 关掉内部比较器,让比较器的输入都为数字口
          movwf   CMCON
          movlw   0C0h              ; 使能周边外设中断和全局中断
          movwf   INTCON
          movlw   b'00000001'       ; Timer1是1:1预分频,内部时钟源,
          movwf   T1CON             ; 振荡频率/4,不带门控
          movlw   .16               ; AD 次数 = 10
          movwf   COUNTER
MAIN010   btfss   CALCULATE_AD      ; = 1 ->  主循环
          goto    MAIN010
          bcf     CALCULATE_AD      ; 清 A/D 转换标志
          bsf     STATUS,RP0        ; 选择bank1
          movf    ADRESL,W          ; W = AD L
          addwf   adsum,F           ; adsum = AD L
          btfsc   STATUS,C          ; C = 0 ->
          incf    adsum+1,F         ; adsum+1 = adsum+1 + 1
          bcf     STATUS,RP0        ; 选择Bank0
          movf    ADRESH,W          ; W = AD H
          addwf   adsum+1,F         ; adsum+1 = AD H
          bsf     ADCON0,GO_DONE    ; 启动 AD 下一次转换
          decfsz  COUNTER,F         ; 转换 计数器 - 1 = 0 ->
          goto    MAIN010           ; 循环
          movfw   adsum
          movwf   result            ; result = w
          CALL    LED000
          movfw   adsum+1
          movwf   result            ; result = w
          CALL    LED000
          movlw   .16               ; AD 次数 = 10
          movwf   COUNTER
          clrf    adsum             ; 清 A/D 累加和 / 平均值 寄存器
          clrf    adsum+1
          goto    MAIN010
          ; / *** *** *** *** *** /   串行输出
LED000    movlw   8                 ; 串行输出 8 位 w = 8
   movwf   count             ; count = w
LED001    bcf     TRISIO,4          ; 清零   
    btfsc   result,0          ; result.7=0 ->
   bsf     TRISIO,4          ; 0010 0000
   bsf     TRISIO,5     ; 产生时钟脉冲 GP4 = 1
   bcf     TRISIO,5          ;              GP4 = 0
   RRF     result,1          ; 左移获取下一个结果位
   decfsz  count,1     ; - 1
   goto    LED001            ; <> 0    循环下位
   RETURN              ; = 0
          ; / *** *** *** *** *** /   
          end                       ; 程序结束符

全部回答
先找个范例,按照范例来写!然后再一步步增加功能!
以前没编过??先找人帮你入门吧。
你好,首先我没用过MAPLAB IDE,我不知道它是否支持你这样写程序,如果用我现在用的仿真器,这段程序是无法编译的,先不谈语法,这段程序无头文件无程序入口。你去找下MAPLAB IDE的错误讯息,会告诉你ERROR152 129分别代表什么。上面显示的是,你这段程序除了伪代码段从第四行开始其他都错了,我只看出最后一行意思是你程序没有期望的END,但是我这里ICE有没有END都无所谓,所以你还是找下你那个IDE的错误讯息吧,所有的错误讯息都会告诉你是为什么,看ERROR后面的数字就行了。
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
外贸知识,找高手把下面文字翻译成英文。大概
骨有裂缝,需要多长时间康复
三国神医 天下癣王抚州市金溪县哪个药房有买
桌上有三个桃子和三个苹果什么意思
人为什么要辛苦赚钱,这是我听过的最好回答!
最亲近的人有时候说的哪句话伤你最深,让你至
k40有车吗?怎么网上买不了票
韩国jm海洋珍珠氨基酸洗面奶怎么分别真假
有谁知道烟台的煤矿哪个存在废弃的矿井?深度
【代春赠】白居易 山吐晴岚水放光,辛夷花白
我想开一家馄饨店,怎样选择店面
我们的平顶教室长为8.5米宽为6米高为4.2米教
2018自持档案怎么激活,我是在天津2006年高职
姓孙,男孩起名字用哪个皓、昊、浩、晧比较好
以恨字开头的成语
推荐资讯
某中国公司预计8月1O日将有一笔100万美元的收
在CS里起什么名字好听
挂靠西藏户口的孩子高考受限制吗
水发木耳后,能直接食用吗?
孩子这次撒谎严重,必须得挨打记住教训,我和
四又2/3×1点5-7/25除以0.24
豪爵铃木原厂机油多少钱一桶?更换DL250需要几
中国真正古董收购公司
在福建有会茅山术的高人吗?我真的很想学,我
求会八字的给翻译成白话文,谢谢!
苏联情怀用俄语怎么说
我们现在没钱 我堂妹的孩子生了送饭的时候我
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?