PIC18F67K22 64MHz下设置UART9600波特率时SPBRGH1寄存器卡0xC2无法修改
核心异常根因
- 最直接的诱因是跨寄存器操作未做bank选址切换:代码仅在最开始切换到了TXSTA1所在的存储bank,后续操作BAUDCON1、SPBRG1、SPBRGH1、RCSTA1时,没有通过
banksel指令切到对应寄存器的物理存储bank,写操作会直接落到当前bank下同偏移地址的无关寄存器上,根本没有写入真正的SPBRGH1。你读回的0xC2就是无关寄存器的固有默认值,和SPBRGH1本身无关。 - 16位波特率模式未真正生效:因为BAUDCON1的操作没有做bank选址,你设置的BRG16位(BAUDCON1 bit3)实际作用在其他寄存器的对应bit上,UART仍然运行在8位波特率模式,SPBRGH1本身就不属于波特率配置链路,自然写入无效。
- 波特率计算值本身存在偏差:64MHz系统时钟、16位BRG、高速波特率模式(BRGH=1)下,9600波特率的理论分频值为
(Fosc/(16*波特率)) -1 = (64000000/(16*9600)) -1 ≈ 417,对应16位寄存器值为0x01A1,你代码中计算的0x1666和理论值偏差超过30%,就算寄存器写入正常,波特率也会完全不匹配。 - 端口配置缺失必要项:TRISC配置值
b'10010000'把RC6(UART1 TX引脚)设为了输入模式,同时没有关闭RC6/RC7端口的模拟功能复用——PIC18F67K22的RC端口默认是模拟输入属性,不关闭模拟功能的话,数字UART功能完全无法正常工作。
修正后的正确配置流程
每一步寄存器操作前必须用banksel切换到对应存储bank,避免地址错位:
; 端口基础配置 banksel TRISC movlw b'01000000' ; RC6(TX1)设为输出,RC7(RX1)保持输入 movwf TRISC banksel ANSEL clrf ANSEL ; 关闭所有端口的模拟功能,切为数字属性 clrf ANSELH ; UART发送控制配置 banksel TXSTA1 movlw b'10000100' ; 使能发送、高速波特率模式、8位数据长度 movwf TXSTA1 ; 波特率发生器模式配置 banksel BAUDCON1 bsf BAUDCON1, 3 ; 开启16位波特率发生器模式 bcf BAUDCON1, 5 ; RX通道数据不反相 bcf BAUDCON1, 4 ; TX通道数据不反相 ; 写入波特率分频值 banksel SPBRGH1 movlw 0x01 movwf SPBRGH1 banksel SPBRG1 movlw 0xA1 movwf SPBRG1 ; 使能UART接收模块 banksel RCSTA1 movlw b'10010000' movwf RCSTA1
注意:配置完成后可以直接读取SPBRGH1、SPBRG1的回读值校验,如果回读值和写入值一致,说明寄存器写入正常;如果回读值仍不对,需要检查工程配置位,确认系统PLL正确锁定64MHz时钟,没有出现时钟源配置错位的问题。
内容的提问来源于stack exchange,提问作者Bobby
相关产品推荐
相关产品推荐

