我使用 MPLabX IDE 5.4 和 XC8 编译器(一种 C/MPASM 混合编译器,具有名为 pic-as v.2.2 的驱动程序作为其汇编器)来编译/汇编一段简单的汇编代码并输出列表文件。
我的整个汇编代码:
PROCESSOR 16F84A
#include <xc.inc>
PSECT code
; a comment
org 00
addlw 01
addlw 02
addlw 03
clrw
loop: addlw 04
goto loop
end loop
Run Code Online (Sandbox Code Playgroud)
列表文件:
从 MPLab X IDE 的反汇编列表文件或通过 CLI 命令生成相同的结果:)$pic-as -mcpu=16F84A -Wa,-a MyAssemblyFile.S -o MyFolder/MyOutputFileName
:
1 processor 16F84A
2 pagewidth 132
3 psect udata,global,class=RAM,space=1,delta=1,noexec
4 psect udata_bank0,global,class=BANK0,space=1,delta=1,noexec
5 psect code,global,class=CODE,delta=2
6 psect data,global,class=STRCODE,delta=2,noexec
7 psect edata,global,class=EEDATA,space=3,delta=2,noexec
8 0089
9 psect code …
Run Code Online (Sandbox Code Playgroud) 我对PIC汇编程序中的银行切换感到困惑......这适用于在usart上放置'Q':
bsf PORTB,1 ;Set Transmit DIR (PORTB (0x6) not mirrored in other banks)
movlw 'Q' ;'Q' to work reg
movwf TXREG ;work reg to TXREG (TXREG (0x19) not mirrored in other banks)
clrwdt ;Clear watchdog
btfss TXSTA,TRMT ;Wait until 'Q' is shifted (TXSTA is 0x18, not mirrored)
goto $-2
bcf PORTB,1 ;Set Recive DIR
Run Code Online (Sandbox Code Playgroud)
这同样有效:
BCF 0x3, 0x5 ;Switch to bank 0
BCF 0x3, 0x6
bsf PORTB,1 ;Set Transmit DIR
movlw 'Q' ;'Q' to work reg
movwf TXREG ;work reg …
Run Code Online (Sandbox Code Playgroud) 我正在研究PIC16F88X的I2C协议.我想做的是根据I2C上接收的数据启用I2C从设备ACK或NACK.
PIC可以对线路上发送的I2C地址进行ACK或NACK,但根据我的读取,它将始终在后续接收的字节上进行ACK.那是对的吗?
在以下沟通中:
Start - I2c_Addr+write/ACK - Register_value/Nack
Run Code Online (Sandbox Code Playgroud)
我希望奴隶能够根据寄存器_
值中的值来确认Ack或Nack .如果从站不理解寄存器_
值,则不应该Ack.
有人可以确认这是不可能的,或告诉我该怎么做?
我正在使用dsPIC33F和GCC.我想向左或向右旋转一个单词中的位,如下所示:
MSB LSB
input: 0101 1101 0101 1101
right: 1010 1110 1010 1110
left : 1011 1010 1011 1010
Run Code Online (Sandbox Code Playgroud)
(如果不清楚,LSB进入MSB的右侧旋转位置,反之亦然.)
我的处理器已经有一个旋转的权利(rrnc,RRC),并向左旋转指令(rlnc,RLC),所以我希望编译器将在优化这一点.如果没有,我可能要使用内联汇编.
我已经能够在我的PIC上运行输出,并且当我设置各种输出锁存器高/低时,可以使一堆LED跳开和关闭.但是,我在阅读状态时遇到了很多困难.
请参阅下面的代码.我设置了我的配置,并将TRISC定义为输入,将TRISB定义为输出.在无限循环中,我检查RC6是高电平还是低电平,并根据结果将整个B锁存器设置为高电平或低电平.
#include <htc.h>
__CONFIG(1, FOSC_IRC & FCMEN_OFF & IESO_OFF);
__CONFIG(2, PWRTEN_OFF & BOREN_OFF & WDTEN_OFF);
__CONFIG(3, MCLRE_OFF);
__CONFIG(4, STVREN_ON & LVP_OFF & DEBUG_OFF);
__CONFIG(5, 0xFFFF);
__CONFIG(6, 0xFFFF);
__CONFIG(7, 0xFFFF);
void main(void)
{
TRISC = 0xFF; // input
TRISB = 0x00; // output
while (1)
{
if (PORTCbits.RC6 == 0)
LATB = 0b00000000;
else
LATB = 0b11111111;
}
return;
}
Run Code Online (Sandbox Code Playgroud)
代码编译良好,没有警告或错误.如果我的代码逻辑只是将锁存器设置为高电平和低电平然后工作正常,但我无法成功读取引脚的状态.
有任何想法吗?
我正在使用PIC18F14K50和MPLAB v8.43以及HiTech ANSI C编译器.
我的连接是+ 5V到VDD(引脚1),VSS(引脚20)到地.我有+ 5V到C6(引脚8),以及从B7(引脚10)到地的100K电阻和LED.要切换RC6,我将电线连接/断开连接到C6.
??????????
+5v -? 01 20 ?- gnd
-? 02 19 ?- …
Run Code Online (Sandbox Code Playgroud) 这是我第一次在C中使用宏而我正在尝试替换我通常放入带宏的函数中的大部分代码.这是一个经常使用的中断的一部分,因此我需要尽可能地优化它.阅读完文档后,我发现编译器不支持函数内联,我想避免函数调用开销.
代码本身将数据发送到串行输入并行移位寄存器,据我所知,编写我需要的代码片段没有更短的方法.
我正在使用C18编译器版本3.41和MPLAB X IDE.
所以这是我在函数形式中使用的代码:
void first_one(void)
{
//3 invisible zeroes
LATBbits.LATB1=0; //data set to zero
LATBbits.LATB0=1;//first clock
LATBbits.LATB0=0;
LATBbits.LATB0=1;//second clock
LATBbits.LATB0=0;
LATBbits.LATB0=1;//third clock
LATBbits.LATB0=0;
//end of invisible zeroes
//two visible zeroes
LATBbits.LATB0=1;//first clock
LATBbits.LATB0=0;
LATBbits.LATB0=1;//second clock
LATBbits.LATB0=0;
//end of two visible zeroes
LATBbits.LATB1=1;//Data is now one
LATBbits.LATB0=1;
LATBbits.LATB0=0;
//one
LATBbits.LATB1=0;//Data is now zero
LATBbits.LATB0=1;//first clock
LATBbits.LATB0=0;
LATBbits.LATB0=1;//second clock
LATBbits.LATB0=0;
//after this, everything should be in place
LATBbits.LATB0=1;
LATBbits.LATB0=0;
}
Run Code Online (Sandbox Code Playgroud)
我已将该函数转换为此宏:
#define first_one() { \
\
LATBbits.LATB1=0;\
\
LATBbits.LATB0=1;\ …
Run Code Online (Sandbox Code Playgroud) 在我提出问题之前,我将介绍问题的背景.
我的PIC 18F汇编程序例程解决了Rntc到T°C的关系.但最好的精度是3位数.
在汇编器示例中使用的NTC参考电阻是10000欧姆,对应于25℃的温度.
只有3位数字,方程式解决方案是= xF6,d246在T的显示屏上显示24到6之间的小数点.
计算T的时间,包括牛顿近似值约为800us.这个计算时间看起来比MPlab C好多了
计算方程y = 9.228*x*x-840.852*x + 25236.82的sqrt的汇编程序会遇到缩放b2-4ac的问题......当我试图包含小数时,数字会溢出我的24位数学套件,例如我必须使用a = 9.b = 840 c = 25236
Q1使用整数,是否有一些技巧使用24位数学计算上述数字?
我的PIC18F87J11一次只能擦除1024个字节.有没有强迫它一次只擦除2个字节或更多?
我正在制作一个Bootloader,有时候只有一行HEX文件(16字节)更改为应用程序,所以我想用新的16字节替换内存中的那一行.如果我尝试擦除这16个字节,则自动擦除1024个字节.然后我被迫重写它们,这需要一些时间并降低Bootloader的速度.
是否有另一种方法可以在不擦除1024个字节的情况下从闪存中擦除某些内容?希望有.
谢谢!
我正在使用XC32编译器为PIC32MX795F512L编写一些代码.我需要从作为void*传递给函数的缓冲区中读取数据.我需要将数据作为无符号32位整数数组读取.问题是当我将void*转换为uint32*并尝试读取该数组的索引0处的值时,处理器会调用一般错误处理程序,而如果我将void*转换为uint8*并执行某些操作位操作得到相同的数据,它工作正常.
代码如下所示:
void foo(void* data, uint32 length)
{
uint32 i,j;
uint32 block;
for(i = 0, j = 0; i < length; i+= sizeof(uint32),j++)
{
printfUART(DEBUG_UART,"Debug 0\r\n");
#if 0//working code
block = ((uint8*)data)[i + 3];
block <<= 8;
block |= ((uint8*)data)[i + 2];
block <<= 8;
block |= ((uint8*)data)[i + 1];
block <<= 8;
block |= ((uint8*)data)[i + 0];
#else//not working code
block = ((uint32*)data)[j];
#endif
printfUART(DEBUG_UART,"Debug 1\r\n");
}
}
Run Code Online (Sandbox Code Playgroud)
如果您更改#if 0
到#if 1
的代码按预期工作,我看到"Debug 0"
和"Debug …
下面是以下C代码的反汇编:
268: while (Counter < 250)
269: {
270: Counter++;
271: }
Run Code Online (Sandbox Code Playgroud)
拆卸:
268: while (Counter < 250)
001B08 370003 BRA 0x1B10
001B10 90406E MOV.B [W14+6], W0
001B12 404FE7 ADD.B W0, #0x7, [W15]
001B14 36FFFA BRA LEU, 0x1B0A
269: {
270: Counter++;
001B0A 90406E MOV.B [W14+6], W0
001B0C E84000 INC.B W0, W0
001B0E 984760 MOV.B W0, [W14+6]
271: }
272:
273: // call foo
274: foo(LAT, 4, Set, &Code);
001B16 203F20 MOV #0x3F2, W0
001B18 40000E ADD W0, W14, W0 …
Run Code Online (Sandbox Code Playgroud)