Код: Выделить всё
Device g16v8a; /* тип мелкосхемы */
pin 2 in1; /* соответствие пинов входам */
pin 3 in2;
pin 4 in3;
pin 5 in4;
pin 12 out1; /* то же для выхода */
/* логика работы */
out1 = (in1 & !in2 & !in3) # in4;
Код: Выделить всё
Device g16v8a; /* тип мелкосхемы */
pin 2 in1; /* соответствие пинов входам */
pin 3 in2;
pin 4 in3;
pin 5 in4;
pin 12 out1; /* то же для выхода */
/* логика работы */
out1 = (in1 & !in2 & !in3) # in4;
Чем не нравятся файлы F41x_UART0_Interrupt.c и F41x_UART_STDIO.c из ...\SiLabs\MCU\Examples\C8051F41x\UART ?Chip115 писал(а):Всем привет! Разбираюсь с UARТ, посему хотелось бы заиметь исходник на сях, где бы производилась настройка и передача данных по UART. контроллер silabs C8051F410
Всем. Мне бы что нить по проще для начала. Без всяких наворотов просто пнуть текст на ком порт и в терминале прочесть данные.Gudd-Head писал(а):Чем не нравятся файлы F41x_UART0_Interrupt.c и F41x_UART_STDIO.c из ...\SiLabs\MCU\Examples\C8051F41x\UART ?Chip115 писал(а):Всем привет! Разбираюсь с UARТ, посему хотелось бы заиметь исходник на сях, где бы производилась настройка и передача данных по UART. контроллер silabs C8051F410
Ну и что? Там что, как-то по-другому инициализируется УАПП и пересылаются данные? Всё расписано подробно и с комментами. Тем более, для инициализации есть утилита Configuration Wizard.Chip115 писал(а):как я понял, это для отладочной платы,которой у меня нет.
и прерывания.equ ActvSens = 0xFE
из них ресет понятно, переполнение таймера привожу ниже, опустошение юсарта - это для вывода очередного сособщения из очереди (записаного в буфер в памяти) и далее два последних не исспользую пока - это забил в шапку на будущее...cseg
.org 0x0000
rjmp RESET ;Reset Handler
.org OVF0addr
rjmp Timer_int ;Timer0 Overflow Interrupt Vector Address
.org UDREaddr
rjmp USARTClear ;UART Data Register Empty Interrupt Vector Address
.org UTXCaddr
rjmp UART_Tx_ok ;UART Transmit Complete Interrupt Vector Address
.org ADCCaddr
rjmp ADC_Int ;ADC Interrupt Vector Address
инициализацию всех портов не привожу там все просто, толькот то что касается трансмитера (косвенно)RESET:
; тут начинается инициализация стека
; потом все подготовительные операции
; настройка портов, таймеров и т.п.
;Инициализация стека
ldi temp, low(RAMEND)
out SPL, temp
ldi temp, high(RAMEND)
out SPH, temp
и ниже по тексту, сразу за портами инициализация USART (31,25 Кбит/с);
ldi temp, 0x0D
out DDRD, temp ;Порт D на смешаный ввод/вывод
ldi temp, 0x0D
out PORTD, temp ;Включаем подтягивающие резисторы на входах
За юсартом:;USART.Mode=32125,N,1(8Mhz)
ldi temp,0x00 ;U2x=0
out UCSRA,temp
ldi temp,(1<<TXEN);Tx_Enable
out UCSRB,temp
ldi temp,(1<<URSEL)|(3<<UCSZ0);Asink+8Bit(Parity_Dsbl,Stp_Bit_1)
out UCSRC,temp
ldi temp,0x00
out UBRRH,r16
ldi temp,0x0F
out UBRRL,temp
;+ первая посылка
ldi temp,ActvSens
out UDR,temp
ну и;Инициализация таймера 0
ldi temp,0x00
out TCNT0,temp
ldi temp,0x00
out OCR0,temp
ldi temp,(5<<CS00);Clk(8Mhz)/1024
out TCCR0,temp
ldi temp,0x00
out TIFR,temp
ldi temp,(1<<TOIE0);Timer_OverFlow_int
out TIMSK,temp
талее тело программы не привожу, т.к. в свете вышеописаного оно не рассматривается, вот прерывание по таймеру:sei ; разрешаем прерывания
Собственно всё, в процессе выдачи именно 0xFE больше ничего не учавствует...Timer_int: ;Active Sensing посылается передатчиком (статус-байт 0xFE (0FEh)) если передачи нету и/или буфер пустой
SBIS UCSRA,5 ;если там и так есть что передавать
RJMP TimerIntEnd ;выходим
ldi temp,ActvSens ;иначе - выгружаем комманду 0xFE
out UDR,temp ;и выплевываем через USART
TimerIntEnd:
reti
Код: Выделить всё
//-----------------------------------------------------------------------------
// F41x_UART0_Interrupt.c
//-----------------------------------------------------------------------------
// Copyright 2006 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
//
// This program demonstrates how to configure the C8051F410 to write to and read
// from the UART interface. The program reads a word using the UART interrupts
// and outputs that word to the screen, with all characters in uppercase
//
// How To Test:
//
// 1) Ensure that jumpers are placed on J27 of the C8051F410 target board
// that connect the P0.4 pin to the TX signal, and P0.5 to the RX signal.
// 2) Ensure that the serial cable is connected to the RS232 connector
// on the target board.
// 3) Specify the target baudrate in the constant <BAUDRATE>.
// 4) Open Hyperterminal, or a similar program, and connect to the target
// board's serial port.
// 5) Download and execute code on an 'F41x target board.
// 6) Type up to 64 characters into the Terminal and press Enter. The MCU
// will then print back the characters that were typed
//
//
// Target: C8051F41x
// Tool chain: Raisonance / Keil
// Command Line: None
//
// Release 1.1 / 11 MAR 2010 (GP)
// -Tested with Raisonance
//
// Release 1.0
// -Initial Revision (SM)
// -5 JUN 2007
//
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <compiler_defs.h>
#include <C8051F410_defs.h> // SFR declarations
#include <stdio.h>
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
#define SYSCLK 24500000 // SYSCLK frequency in Hz
#define BAUDRATE 9600 // Baud rate of UART in bps
//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
void SYSCLK_Init (void);
void UART0_Init (void);
void PORT_Init (void);
void Timer2_Init (int);
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
#define UART_BUFFERSIZE 64
unsigned char UART_Buffer[UART_BUFFERSIZE];
unsigned char UART_Buffer_Size = 0;
unsigned char UART_Input_First = 0;
unsigned char UART_Output_First = 0;
unsigned char TX_Ready =1;
static char Byte;
//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------
void main (void)
{
PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer
// enable)
PORT_Init(); // Initialize Port I/O
SYSCLK_Init (); // Initialize Oscillator
UART0_Init();
EA = 1;
while(1)
{
// If the complete word has been entered via the terminal followed by
// carriage return
if((TX_Ready == 1) && (UART_Buffer_Size != 0) && (Byte == 13))
{
TX_Ready = 0; // Set the flag to zero
TI0 = 1; // Set transmit flag to 1
}
}
}
//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Configure the Crossbar and GPIO ports.
//
// P0.4 digital push-pull UART TX
// P0.5 digital open-drain UART RX
//
//-----------------------------------------------------------------------------
void PORT_Init (void)
{
P0MDOUT |= 0x10; // Enable UTX as push-pull output
XBR0 = 0x01; // Enable UART on P0.4(TX) and P0.5(RX)
XBR1 = 0x40; // Enable crossbar and weak pull-ups
}
//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This routine initializes the system clock to use the internal oscillator
// at its maximum frequency.
// Also enables the Missing Clock Detector.
//-----------------------------------------------------------------------------
void SYSCLK_Init (void)
{
OSCICN = 0x87; // configure internal oscillator for
// 24.5MHz
RSTSRC = 0x04; // enable missing clock detector
}
//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1.
//-----------------------------------------------------------------------------
void UART0_Init (void)
{
SCON0 = 0x10; // SCON0: 8-bit variable bit rate
// level of STOP bit is ignored
// RX enabled
// ninth bits are zeros
// clear RI0 and TI0 bits
if (SYSCLK/BAUDRATE/2/256 < 1) {
TH1 = -(SYSCLK/BAUDRATE/2);
CKCON |= 0x08; // T1M = 1; SCA1:0 = xx
} else if (SYSCLK/BAUDRATE/2/256 < 4) {
TH1 = -(SYSCLK/BAUDRATE/2/4);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 01
CKCON |= 0x01;
} else if (SYSCLK/BAUDRATE/2/256 < 12) {
TH1 = -(SYSCLK/BAUDRATE/2/12);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 00
} else if (SYSCLK/BAUDRATE/2/256 < 48) {
TH1 = -(SYSCLK/BAUDRATE/2/48);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 10
CKCON |= 0x02;
} else {
while (1); // Error. Unsupported baud rate
}
TL1 = TH1; // init Timer1
TMOD &= ~0xf0; // TMOD: timer 1 in 8-bit autoreload
TMOD |= 0x20;
TR1 = 1; // START Timer1
TX_Ready = 1; // Flag showing that UART can transmit
IP |= 0x10; // Make UART high priority
ES0 = 1; // Enable UART0 interrupts
}
//-----------------------------------------------------------------------------
// Interrupt Service Routines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// UART0_Interrupt
//-----------------------------------------------------------------------------
//
// This routine is invoked whenever a character is entered or displayed on the
// Hyperterminal.
//
//-----------------------------------------------------------------------------
void UART0_Interrupt (void) interrupt 4
{
if (RI0 == 1)
{
if( UART_Buffer_Size == 0) { // If new word is entered
UART_Input_First = 0; }
RI0 = 0; // Clear interrupt flag
Byte = SBUF0; // Read a character from UART
if (UART_Buffer_Size < UART_BUFFERSIZE)
{
UART_Buffer[UART_Input_First] = Byte; // Store in array
UART_Buffer_Size++; // Update array's size
UART_Input_First++; // Update counter
}
}
if (TI0 == 1) // Check if transmit flag is set
{
TI0 = 0; // Clear interrupt flag
if (UART_Buffer_Size != 1) // If buffer not empty
{
// If a new word is being output
if ( UART_Buffer_Size == UART_Input_First ) {
UART_Output_First = 0; }
// Store a character in the variable byte
Byte = UART_Buffer[UART_Output_First];
if ((Byte >= 0x61) && (Byte <= 0x7A)) { // If upper case letter
Byte -= 32; }
SBUF0 = Byte; // Transmit to Hyperterminal
UART_Output_First++; // Update counter
UART_Buffer_Size--; // Decrease array size
}
else
{
UART_Buffer_Size = 0; // Set the array size to 0
TX_Ready = 1; // Indicate transmission complete
}
}
}
//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------
... прерывание происходит при RI0 == 1 или ТI0 == 1, т.е. при окончании приема или передачи байта.Chip115 писал(а):не могу понять как работает программа? когда происходит прерывание? В отладчике постоянно крутится в главном цикле и не переходит в подпрограмму обработки прерывания
Да, хорошо.ploop писал(а):Господа, вкладывайте, пожалуйста, большие простыни кода в файлы, раз спойлеров форум не поддерживает.
т.е. может быть такое что проблема не в прошивке/железе а в способе принятия информации компом?E0 00 00 Pitch bend
E0 00 00 Pitch bend
E0 00 00 Pitch bend
E0 00 00 Pitch bend
E0 00 00 Pitch bend
E0 00 00 Pitch bend
...
ActvSns - это регистр r8, в котором я храню свое 0xFE (ну или 0х00 в последнем "опыте") и больше нигде в другом месте этот регистр не трогаю...Timer_int:
SBIS UCSRA,5
reti
out UDR,ActvSns
reti
Wtf? Что за два reti подряд???DJ_Kiridza писал(а):Timer_int:
SBIS UCSRA,5
reti
out UDR,ActvSns
reti
почему подряд? один без вывода в UDR, другой после вывода... только вот привычка писать номер бита вместо его имени не позволяет понять, когда же именно UDR обновляется...Gudd-Head писал(а):Wtf? Что за два reti подряд???DJ_Kiridza писал(а):Timer_int:
SBIS UCSRA,5
reti
out UDR,ActvSns
reti
Разве МК дойдёт до второго reti?ARV писал(а):почему подряд?
- ну извините - это мой первый в жизни код... малоопытный я покатолько вот привычка писать номер бита вместо его имени не позволяет понять, когда же именно UDR обновляется...