找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2752|回复: 13
收起左侧

一个初学者请教老师傅这个PIC单片机程序为什么不运行?

[复制链接]
ID:248656 发表于 2019-3-23 18:58 | 显示全部楼层 |阅读模式
tmr0 equ 01h                   ;定义TMR0定时器/计数器的地址
status equ 03h                 ;定义状态寄存器地址
portd equ 08h                  ;定义端口D的寄存器的地址
trisd equ 88h                  ;定义端口D的方向控制寄存器的地址
option_reg equ 81h             ;定义选项寄存器的地址
intcon equ 0bh                 ;定义一个中断端控制寄存器的地址
c equ 0                        ;定义状态寄存器进位标志C的指示位
rp0 equ 5h                     ;定义状态寄存器页选位的指示位
w equ 0                        ;定义传送目标寄存器为W的指示位
f equ 1                        ;定义传送目标寄存器为F的指示位
z equ 2                        ;定义状态寄存器零标志Z的指示位
t0if equ 2                     ;定义TMR0的溢出标志位
t0ie equ 5                     ;定义TMR0的使能标志位
flag equ 24h                   ;定义一个亮灭标志位
flag2 equ 25h                  ;定义一个左右移标志
m equ 8                        ;定义一个常数寄存器
dly1 equ 20h                   ;定义一个延时变量寄存器
dly2 equ 21h                   ;定义另一个延时变量寄存器
portd_b equ 23h                ;定义一个显示缓冲区
w_temp equ 7fh                 ;定义一个W备份寄存器
tmr0_d equ 0                   ;定义TMR0的初始值
;--------------------------------- 付复位向量------------------------
org 000h                       ;定义程序存放区域的起始位置
nop                            ;设置一条ICD必须的空操作指令
goto main                      ;
;----------------------------中断向量和中断服务子程序----------------
org 004h                       ;
tmr0serv                        ;中断服务子程序名称
movwf w_temp                   ;复制W倒塌的临时备份寄存器W_TEMP中
bcf intcon,t0if                ;清除TMR0溢出中断标志位
incf flag,f                    ;亮灭标志位(寄存器末位)翻转
btfss flag,0                   ;标志位=1?是!跳一步到“熄灭”
goto jump0                     ;否,跳到“点亮”
clrf portd                     ;熄灭
goto jump1                     ;跳过下面的程序
jump0                           ;
movf portd_b                   ;点亮,即将缓冲区内容先传入W
movwf portd                    ;再由W转入端口寄存器,送显
jump1                           ;
movlw tmr0_d                   ;TMR0赋初值
movwf tmr0                     ;并(重新)启动定时器
movf w_temp,w                  ;恢复现场
retfie                         ;中断返回
;----------------------------------主程序----------------------------
main
bsf status,rp0                 ;选择文件寄存器的体1
movlw 00h                      ;将端口D的方向控制码00H先送W
movwf trisd                    ;端口D得方向控制寄存器,设定为输出
movlw 07h                      ;将选项寄存器的控制码07H先送W
movwf option_reg               ;设定分频比1:256
bcf status,rp0                 ;恢复状态寄存器的体0
movlw 0a0h                     ;将中断控制寄存器的控制码A0H先送W
movwf intcon                   ;开放全局中断和TMR0中断
bcf intcon,t0if                ;清除TMR0溢出中断标志位
movlw tmr0_d                   ;TMR0赋初值
movwf tmr0                     ;启动定时器
movlw 0feh                     ;显示驱动码送入W
movwf portd_b                  ;显示驱动码送显示缓冲寄存器
bsf status,c                   ;   
l1
movlw 01h                      ;
xorwf flag2,f                  ;      
btfss flag2,0                  ;判断左右移标志=1,左移
goto loop                      ;右移
goto loop1                     ;左移
loop
movlw 0ah
movwf m
m1
decfsz m,f
goto c1
goto m2
c1
rrf portd_b
goto m1
m2                   ;带进位标志位循环右移缓冲区寄存器
goto l1                        ;跳转到L1
loop1
movlw 9
movwf m
s2
decfsz m,f
goto k1
goto k2
k1  
rlf portd_b
goto s2
k2                    ;带进位标志位循环左移缓冲区寄存器
goto l1                        ;跳转到L1                           
;-----------------------延时子程序-----------------------------
delay
movlw 0ffh                     ;将外层循环变量值送W
movwf dly1                     ;送入用作外循环变量的DLY1
lp0
movlw 0ffh                     ;将内层循环变量值送W
movwf dly2                     ;送入用作内循环变量的DLY2
lp1
decfsz dly2,f                  ;内层变量DLY2内容递减,若为0跳跃
goto lp1                       ;跳转到LP1
decfsz dly1,f                  ;外层变量DLY1内容递减,若为0跳跃
goto lp0                       ;跳跃LP0
return                         ;返回主程序
end                            ;

回复

使用道具 举报

ID:401564 发表于 2019-3-24 04:48 | 显示全部楼层
什么叫不运行呢?你从哪里看出来不运行了?
你的程序估计没几个看得明白,PIC没有像8051那样明显的标号,你就应该搞什么虚线之类的分开,好让人找到GOTO指令跳转到哪里了
估计你这是仿真的吧
代码的开头没有配置单片机的晶振,复位电压之类的
像这样:#include <p16f877a.inc>        ;包含了PIC16F877A的寄存器声称文件
    __CONFIG _FOSC_HS & _WDTE_OFF & _PWRTE_OFF & _BOREN_ON & _LVP_OFF & _CPD_OFF & _WRT_OFF & _CP_OFF
回复

使用道具 举报

ID:248656 发表于 2019-3-24 07:47 | 显示全部楼层
我将程序烧到板子上,我设计的是流水灯,但是出来的结果是8个灯全亮常亮
回复

使用道具 举报

ID:123289 发表于 2019-3-24 08:04 | 显示全部楼层
除了时钟被关闭之外,单片机就没有不运行时候!
回复

使用道具 举报

ID:248656 发表于 2019-3-28 17:32 | 显示全部楼层
配置位设置
FOSC=HS OSCILLATOR
WDTE=DISABLE
PWRTE=DISABLE
BORETN=DISABLE
LVP=HV ON MCLR MUST BE USED
CPD=OFF
WRT=OFF
CP=OFF
回复

使用道具 举报

ID:401564 发表于 2019-3-28 19:24 | 显示全部楼层
asd-123 发表于 2019-3-28 17:32
配置位设置
FOSC=HS OSCILLATOR
WDTE=DISABLE

配置位应该是在代码里面的,而且还得开关就是的,我用过PIC16F877A,就是这样的
回复

使用道具 举报

ID:248656 发表于 2019-3-29 18:15 | 显示全部楼层
汇编语言能够设置配置位吗?在程序里如何编写?
回复

使用道具 举报

ID:248656 发表于 2019-3-29 18:42 | 显示全部楼层
tmr0 equ 01h                ;定义定时器和计数器0寄存器地址
pcl equ 02h                 ;定义程序计数器低字节寄存器地址
status equ 03h              ;定义状态寄存器地址
option_reg equ 81h          ;定义选项寄存器地址
intcon equ 0bh              ;定义中断寄存器地址
portd equ 08h               ;定义端口D的数据寄存器的地址
trisd equ 88h               ;定义端口D的方向控制寄存器地址
dly equ 20h                 ;定义一个外循环延时变量
dly1 equ 21h                ;定义一个内循环变量延时变量
flag1 equ 22h               ;定义一个左右移标志
flag2 equ 23h               ;定义一个亮灭标志
w_temp equ 24h              ;定义一个临时备份寄存器
portd_b equ 25h             ;定义一个显示缓冲区寄存器
m equ 26h                   ;定义一个计数器变量
w equ 0                     ;定义传送目标寄存器为W的指示位
f equ 1                     ;定义传输目标寄存器为RAM的指示位
tmr0_b equ 0                ;定数器初始值
rp0 equ 5                   ;在状态寄存器中的页选位0
t0if equ 2                  ;定义TMR0的中断标志位
;-------------------------------复位向量-------------------------------------
org 000h                   ;设置复位矢量
nop                        ;放置一条ICD必须的空操作
goto main                  ;跳转到主程序
;-----------------------中断向量和中断服务程序-------------------------------
org 004h                  ;
tmr0serv                    ;中断服务子程序
movwf w_temp               ;复制W到他的临时备份寄存器W—temp中
bcf intcon,t0if            ;清除TMR0溢出中断标志位
incf flag2,f               ;亮灭标志位(寄存器)反转
btfss flag2,0               ;标志位=1?是!跳一步到熄灭“
goto jump                  ;否!跳到”点亮“
goto jump1                 ;熄灭
;----------------------------熄灭-------------------------------------------
jump                        ;
movlw portd_b              ;点亮,即将缓冲区先送入W
movwf portd                ;再由W转入端口D寄存器,送显
;-----------------------------点亮----------------------------------------------
jump1                       ;
movlw 0ffh                 ;将立即数0FFH先送到W
movlw portd                ;熄灭
movlw tmr0_b               ;TMR0赋初值
movwf tmr0                 ;启动定时器
movf w_temp,w              ;恢复现场
retfie                     ;中断返回
;-------------------------------主程序---------------------------------------
main                        
bcf status,rp0             ;设置文件寄存器的体1
movlw 00h                  ;将端口D的方向控制码00H先送到W
movwf trisd                ;转送到方向寄存器,端口D设为输出
movlw 07h                  ;设定选项寄存器内容,分频器给TMR0
movwf option_reg           ;分频比为1:256
bcf status,rp0             ;恢复状态寄存器的体0
movlw 0a0h                 ;将中端控制码先送W
movwf intcon               ;开放全局中断和定时器0中断
bcf intcon,t0if            ;清除TMR0溢出中断标志位
movlw tmr0_b               ;TMR0赋初值
movwf tmr0                 ;启动TMR0定时计数器
movlw 0feh                 ;将驱动码送入W
movwf portd_b              ;将驱动码送入显示缓冲区
call delay                 ;延时子程序
clrf flag1                 ;清零标志位
;-----------------------------------------------------------------------------
l1
movlw 01h                  ;将立即数01H先送W
xorwf flag1,f              ;和FLAG2相或,标志位取反
btfss flag1,0              ;测试标志位=1,是跳到左移。否!跳到右移
goto loop                  ;否!右移
goto loop1                 ;是!跳到左移
;---------------------------右移子程序-----------------------------------------
loop
movlw 09                   ;将计数初值送W
movwf m                    ;再转送到M
;------------------------------------------------------------------------------
m1
decfsz m,f                 ;计数器减一,为0,跳一步。不为0,右移
goto c1                    ;跳到C1(右移)
goto c2                    ;计数器为0返回,循环检测
;----------------------------------右移-------------------------------------------
c1
rrf portd_b,f                ;带进位循环右移指令
goto m1                    ;返回计数器
;----------------------------------返回计数器--------------------------------------------
c2
goto l1                    ;返回检测左右移标志位
;----------------------------左移子程序----------------------------------------
loop1
movlw 9                    ;将计数器初值先送W
movwf m                    ;转送到M
;------------------------------------------------------------------------------
s2
decfsz m,f                 ;计数器减一,为0,跳一步,否,顺序执行
goto k1                    ;跳到左移
goto k2                    ;计数器为0返回,循环检测
;------------------------------------------------------------------------------
k1
rlf portd_b,f                ;带进位循环左移
goto s2                    ;返回计数器
;------------------------------------------------------------------------------
k2
goto l1                    ;跳回检测左右移标志
;-----------------------------延时子程序----------------------------------------
delay
movlw 0ffh                 ;将外层循环参数0FF先送W
movwf dly                  ;再转送到DLY
;-------------------------------------------------------------------------------
lp0
movlw 0ffh                 ;将内层循环参数0FFH先送W
movwf dly1                 ;再转送到DLY1
;-------------------------------------------------------------------------------
lp1
decfsz dly1,f              ;内层循环参数DLY1自减一,若为0,跳一步
goto lp1                   ;返回循环自减LP1
decf dly,f                 ;外层循环参数DLY自减一,若为0,跳一步
goto lp0                   ;跳回循环自减LP0
return                     ;返回主程序
end                        ;源程序结束
我从写了一下
配置位设置
FOSC=HS OSCILLATOR
WDTE=DISABLE
PWRTE=DISABLE
BORETN=DISABLE
LVP=HV ON MCLR MUST BE USED
CPD=OFF
WRT=OFF
CP=OFF
机子就是不运行,怎么回事?????????
回复

使用道具 举报

ID:342822 发表于 2019-3-29 19:13 | 显示全部楼层
没问题~pic16f577可以运行。
回复

使用道具 举报

ID:342822 发表于 2019-3-29 19:27 | 显示全部楼层
仿真可以运行
捕获.PNG
回复

使用道具 举报

ID:401564 发表于 2019-3-29 22:04 | 显示全部楼层
asd-123 发表于 2019-3-29 18:42
tmr0 equ 01h                ;定义定时器和计数器0寄存器地址
pcl equ 02h                 ;定义程序计 ...

在代码的第一行呀!注释不算,配置位在所有代码的前面
但我不知道你用的是什么版本的IDE,我用mplab x ide就是这样子的,在配置位设定那设定好配置位,然后再生成代码,再粘贴到代码的开始
这是一个我用PIC16F877A写的一个ADC程序,已经在开发板上验证成功过的了 PIC16F877A_ADC.rar (1.77 KB, 下载次数: 10)
回复

使用道具 举报

ID:248656 发表于 2019-3-30 07:35 | 显示全部楼层
我也是头一个遇到,试了好几遍,不行我用的芯片PIC877A
回复

使用道具 举报

ID:401564 发表于 2019-3-30 11:44 | 显示全部楼层
asd-123 发表于 2019-3-30 07:35
我也是头一个遇到,试了好几遍,不行我用的芯片PIC877A

你试了我给你的程序没有?
不要仿真,要在实际的PCB板上运行的,不一定要完全的接上显示,至少是输出和ADC端口随便接一下,也不一定要数码管,LED接上几个也行,只要是能确定程序已经在运行就可以了
你用的IC和我用的是一样的,代码是可以兼容的
回复

使用道具 举报

ID:248656 发表于 2019-4-7 20:30 | 显示全部楼层
老师,我试了。谢谢,能多给接例子好让我学习进步老师能把电话给我吗?我要多请教
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表