Прерывание и использование UART
Я борюсь за проект, и вот я здесь.
Моя проблема заключается в отправке данных через UART. На самом деле проблема не в этом, потому что мне удается отправлять данные благодаря:
int x=1;
#define var 00000001
void InitUART()
{
mPORTFClearBits(BIT_8);
TRISFbits.TRISF8=0; // RF8 output==>TX1
TRISFbits.TRISF1=1; // RF1 input==>RX1
U1STA = 0x1400; // Enable Tx(inv) and Rx
//U1BRG = 8332; // value = (80000000 / BAUD) - 1 = 9600
U1MODE = 0x8008; // Enable UART with 1 stop bit, no parity and BRGH
OpenUART1(UART_EN | UART_BRGH_FOUR, UART_RX_ENABLE | UART_TX_ENABLE,U1BRG(UART1_BAUD) );
}
int main(void) {
InitUART;
while (1)
{
x|=var;
x=x<<1; //=> 0000 0010
x=x<<1; //=> 0000 0101
x|=var;
x=x<<1; //=> 0000 1011
x|=var;
x=x<<1; //=> 0001 0110
x=x<<1; //=> 0010 1101
x|=var;
x=x<<1; //=> 0101 1010
x=x<<1; //=> 1011 0100
//uart_send_data((BYTE*)x,8);
U1TXREG=x;
}
И я получаю хорошо.
Но я хочу использовать прерывание ChangeNotice. Это код, похожий на этот, и он работает:
void InitISR()
{
SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
PORTSetPinsDigitalIn(IOPORT_B, BIT_2); //RB2 as input for CN4 operation
mPORTBClearBits(BIT_2);
mCNOpen(CONFIG, PINS, PULLUPS);
// mCNClearIntFlag(); // clear interrupt flag
temp=mPORTBRead(); // clear port mismatch
ConfigIntCN(INTERRUPT); // enable CN interrupt
INTEnableSystemMultiVectoredInt();
TRISEbits.TRISE0= 1; //E0 input // SCL EST BRANCHE EN E0/D0
TRISEbits.TRISE1= 1; //E1 input // SDA EST BRANCHE EN E1/D1
TRISEbits.TRISE2= 0; //D2 output
TRISEbits.TRISE3=0;
LATEbits.LATE2=0;
LATEbits.LATE3=0;
}
void __ISR(_CHANGE_NOTICE_VECTOR,ipl6) ChangeNotification_Handler(void)
{
LATEbits.LATE2=0; //To know
LATEbits.LATE2=1; // that interrupt
LATEbits.LATE2=0; // is working
if ((mPORTEReadBits(BIT_0))!=0) //Check if clock is high==> sending data
{
nbr++;
SDA=mPORTEReadBits(BIT_1);
if (SDA==0) // data =0?
{
i=i<<1;
}
else // data !=0 ==> 1
{
i=i<<1;
i|=var;
} }
else
{
if (nbr==8) // 8bits=>1byte
{
U1TXREG = i;
nbr=0;
}
else
{
}
}
temp=mPORTBReadBits(BIT_2);
mCNClearIntFlag();
}
Но когда я делаю и то, и другое, оно отправляет что-то, но не совсем то, что я ищу, оно отправляет (в гекса) 000 224 224 000 224 224 00 224 224 000. И вместо того, чтобы получать байт на байт, я Получаю 14 байтов на 14 байтов.
Итак, я подумал, что UART приносит прерывание, и я попытался отключить его, используя asm("di");
или же IEC0bits.U1TXIE=0;
или же IEC0bits.U1TXIE=0;
но без каких-либо последствий... Так что, если кто-то знает, почему у меня такая проблема, я был бы так счастлив =D
Приветствия.
1 ответ
Итак, я публикую это для кого-то, у кого может быть та же самая проблема, однажды. Проблема была только в часах. Даже если у вас есть специальный кварц, вам нужно определить системные часы. И, когда ваши системные часы установлены, вы должны определить свои периферийные часы, да еще один. Но будьте осторожны, я думаю, что не все периферийные контакты работают на периферийных часах.
Итак, у меня кварц 48 МГц, и мой код здесь:
//48Mhz
//I want SYS_CLOKC=40Mhz
#pragma config UPLLEN = OFF // USB PLL Enabled, OFF si quartz 48 MHz
#pragma config FPLLIDIV = DIV_12 // PLL Input Divider, il faut obtenir
// entre 4 et 5 MHz
#pragma config FPLLMUL = MUL_20 // PLL Multiplier
#pragma config FPLLODIV = DIV_2 // PLL Output Divider
// périphérique clock 5Mhz = SYSCLK/FPBDIV
#pragma config FPBDIV = DIV_8 // Peripheral Clock divisor
// oscillateur : Primary Osc w/PLL (XT+,HS+,EC+PLL)
#pragma config POSCMOD = HS // Primary Oscillator
#pragma config FNOSC = PRIPLL // Oscillator Selection
#pragma config FWDTEN = OFF // Watchdog Timer
#pragma config CP = OFF // Code Protect
48/12 = 4МГц
4*20=80МГц
80/2=40 МГц System_CLOCK=40 МГц
40/8=5 МГц Периферийные часы = 5 МГц
Что касается остального кода, я не могу вам это объяснить, я нашел весь блок, и он работает так, вот так...