我的项目包括:
使用4位7段显示器显示某些数字,代表存钱罐中存放的现金金额。我正在使用
.c
和 .S
文件。
为了在 4 位数字之间循环,我使用了 4ms TIMER0 中断,其 ISR 调用汇编函数。除了该中断之外,我正在使用“更改中断”,但这部分工作得很好,因此我将其从我共享的代码中删除了。
器件:PIC16F18855; MPLABxIDE 5.45; XC8 编译器。
所以,这是 main.c 脚本(请原谅西班牙语注释):
#include <xc.h>
// INICIO DE PRIVATE CODE
// Se incluyen los headers
#include "system.h"
// Declaración de funciones
void TMR0_ISR_DISPLAY4(void); // Corrección en los parámetros
extern void DISPLAY4();
void array_digitos4(unsigned int); // Función para obtener el array de números a mostrar en el display 4 segmentos
// Declaración de variables globales
volatile unsigned char tecla, compart;
volatile unsigned int TOTAL = 0; // Cantidad total de dinero en la alcancía
volatile unsigned int X = 0; // Cantidad en un compartimiento (A, B, C, D)
volatile unsigned int Y = 0;
volatile unsigned int totales_ar[4] = {0, 0, 0, 0}; // Los totales se acumulan en un array
volatile unsigned char etapa = 0;
volatile unsigned char digito = 0;
volatile unsigned char digitos4[4] = {0, 0, 0, 0};
volatile unsigned char D0, D1, D2, D3;
int main(void){
// Inicialización de periféricos
SYSTEM_Initialize();
// Configuración del handler para TMR0 ISR
TMR0_OverflowCallbackRegister(TMR0_ISR_DISPLAY4);
INTCONbits.GIE = 1;
INTCONbits.PEIE = 1;
INTCONbits.INTEDG = 0;
while(1){
// Tu bucle principal
__asm("nop");
__asm("nop");
__asm("nop");
}
}
// Implementación de la ISR
void TMR0_ISR_DISPLAY4(void){
// Deshabilito interrupciones
INTCONbits.GIE = 0;
// Llamada a la función en ensamblador con los parámetros
switch(etapa){
case 0:
array_digitos4(TOTAL);
break;
case 1:
if(digito == 0){
array_digitos4(X);
}
else{
array_digitos4(Y);
}
break;
case 2:
array_digitos4(totales_ar[compart]);
break;
}
DISPLAY4();
// Salir de la ISR
PIR0bits.TMR0IF = 0;
INTCONbits.GIE = 1;
}
void array_digitos4(unsigned int numero){
unsigned int dividendo = numero;
unsigned int divisor = 1000; // Iniciar con 1000 para el primer dígito
// Descomponer el número en dígitos
for (int i = 0; i < 4; i++){
if(digitos4[i] >= divisor){
//digitos4[i] = (char)(dividendo/divisor); // Obtener el dígito correspondiente
digitos4[i] = (char)(10);
}
else{
digitos4[i] = 0;
}
dividendo = dividendo%divisor; // Reducir el número eliminando el dígito extraído
divisor = divisor/10; // Reducir el divisor para el siguiente dígito
}
D0 = digitos4[0];
D1 = digitos4[1];
D2 = digitos4[2];
D3 = digitos4[3];
}
现在,DISPLAY4.S,这是脚本失败的部分:
#include <xc.inc>
GLOBAL _DISPLAY4 ; Hacer la función accesible desde C
PSECT text, class = CODE, local, delta = 2
; Definir variables manualmente en la RAM
extern _D3
extern _D2
extern _D1
extern _D0
_DISPLAY4:
; Operación con PORTC para encender el digito correcto
BANKSEL (PORTC) ; Seleccionar el banco de PORTC
movf _D3, W ; Leer PORTC en W
movwf PORTC
如何访问.c文件中声明和计算的变量?比如说,将内容从 D0、D1、D2 或 D3 移动到 .S 文件中的 PORTC?该端口控制前面提到的显示。
该值通过w寄存器传输。如果您在 xc8 代码中调用汇编程序子例程。
DISPLAY(4); //the value '4' is loaded into the w register
w
寄存器加载值4。
在汇编程序例程中,已知 w 寄存器已经加载了值 4。
_DISPLAY4
movwf PORTC ;pushes the value 4 to port C
ret
知道将此值放入端口。