kang2008
Guest
|
|
« on: April 08, 2008, 08:32:12 08:32 » |
|
//Initialize software USART by configuring the PORT void initUART() { PORT |=0b001000; //Set PB3 (Transmitter Pin) DDRB |=0b001000; //Configure PB3 as output pin DDRB &=0b101111; //Configure PB4(Reciever Pin) as input pin }
//Function to transmit a character through software USART /* Baud Rate : 9600 bps Data Bits : 8 Stop Bits : 1 Parity : None Flow Cotrol : None */
void send_char(unsigned char c) { unsigned char i;
initUART(); //Initialize the software USART //Transmit a start Bit PORTB &= 0b110111; bit_delay();
//Transmit the remaining 8 bits for(i=0;i<8;++i) { if((c & 0x01) == 0x01) //Check if LSB is 1 PORTB|=0b001000; //Send a One else //Otherwise PORTB&=0b110111; //Send a 0
bit_delay(); //Wait for one bit length c = c >> 1; //Right Shift the bits so that the //next bit to be transmitted becomes LSB }
//IDLE High (Including a Stopbit) PORTB|=0b001000; //Byte Delay for(i=0;i<25;i++) bit_delay(); }
int get_char(void) { unsigned char i; unsigned char data;
initUART(); //Initialize the software USART //Transmit a start Bit PINB &= 0b101111; bit_delay();
//Transmit the remaining 8 bits for(i=0;i<8;++i) { if((c & 0x01)==0x01) //Check if LSB is 1 PINB |= 0b010000; //Send a One else //Otherwise PINB &= 0b101111; //Send a 0
bit_delay(); //Wait for one bit length c = c >> 1; //Right Shift the bits so that the //next bit to be transmitted becomes LSB }
//IDLE High (Including a Stopbit) PINB |= 0b010000; //Byte Delay for(i=0;i<25;i++) bit_delay(); return c; }
i do not know get_char() function?
thank you.
Posted on: April 08, 2008, 08:17:01 08:17 - Automerged
other:
int get_char(void) { unsigned char i; unsigned char data;
initUART(); //Initialize the software USART //Transmit a start Bit //PINB &= 0b101111; //bit_delay();
data = 0; //Transmit the remaining 8 bits for(i=0;i<8;++i) { data <<= 1; bit_delay();
if(data == 1) //Check if LSB is 1 PINB |= 0b010000; //Send a One else //Otherwise PINB &= 0b101111; //Send a 0 }
//Byte Delay for(i=0;i<25;i++) bit_delay(); return data; }
|
|
|
Logged
|
|
|
|
zuisti
Senior Member
Offline
Posts: 409
Thank You
-Given: 242
-Receive: 780
|
|
« Reply #1 on: April 08, 2008, 11:55:43 11:55 » |
|
Hi 'kang2008'
Your first function (send_char) may work yet even, if you are using the proper bit-time delay and this doesn't disturb with any IT routines. Maybe it's needed the disabling of all interrupts along it sends a char. However, the long delaying at the end is unnecessary, the overall speed (chars/sec) will too slow so.
But ... the get_char will NOT work without any start bit falling edge detection. Now it get ever garbage only.
This detection is possible via polling or also via IT. And it's better using first a half bit-time delay after the detected start edge (and exit if the RX pin doesn't zero yet), and from here examine and get 9 times (after full bit-time delays) the pin value. The 9th bit is the stop bit ( do not store), but it must exist as a high level.
I'm attached here a zip with old but useful PDFs about this thing.
Hope this helps zuisti
|
|
|
Logged
|
|
|
|
kang2008
Guest
|
|
« Reply #2 on: April 08, 2008, 02:05:47 14:05 » |
|
hi. zuisti thank you.
;*************************************************************************** ;* ;* "getchar" ;* ;* This subroutine receives one byte and returns it in the "Rxbyte" register ;* ;* Number of words :14 including return ;* Number of cycles :Depens on when data arrives ;* Low registers used :None ;* High registers used :2 (bitcnt,Rxbyte) ;* Pointers used :None ;* ;***************************************************************************
getchar: ldi bitcnt,9 ;8 data bit + 1 stop bit
getchar1: sbic PIND,RxD ;Wait for start bit rjmp getchar1
rcall UART_delay ;0.5 bit delay
getchar2: rcall UART_delay ;1 bit delay rcall UART_delay
clc ;clear carry sbic PIND,RxD ;if RX pin high sec ;
dec bitcnt ;If bit is stop bit breq getchar3 ; return ;else ror Rxbyte ; shift bit into Rxbyte rjmp getchar2 ; go get next
getchar3: ret
possiable asm to c source?
|
|
|
Logged
|
|
|
|
zuisti
Senior Member
Offline
Posts: 409
Thank You
-Given: 242
-Receive: 780
|
|
« Reply #3 on: April 08, 2008, 03:03:07 15:03 » |
|
Hi Kang2008,
It's easy but depends from your C dialect (red is error handling only): (PORTB.4 = RX pin)
int Get_Char(void) { char n, int ch; do while (PORTB.4); // a loop for waiting the start bit falling edge (until pin goes low) delay_05bit(); if (PORTB.4) // if high, it's not a real start bit !! return (-1); // or other value, error for ( n = 8, ch = 0 ; n ; --n ) { delay_05bit(); delay_05bit(); //1 bit delay ch >>= 1; if (PORTB.4) ch += 0x80; } delay_05bit(); delay_05bit(); //1 bit delay if (!PORTB.4) //stop bit (1) exists? if not, error return (-1); // or other value, error delay_05bit(); // wait for end of stop bit return ((int) ch); //received char }
Not tried !! zuisti
|
|
|
Logged
|
|
|
|
kang2008
Guest
|
|
« Reply #4 on: April 08, 2008, 03:39:35 15:39 » |
|
other do not test in the get_char() function?
// 4.6mhz attiny13 (DO NOT USED 8CKDIV) // Include Directives #include <avr/io.h> #include <avr/interrupt.h> #include <avr/SIGNAL.h> #include <avr/sleep.h>
#define sbi(PORT,BIT) PORT|= _BV(BIT) #define cbi(PORT,BIT) PORT&=~_BV(BIT)
void bit_delay(); //A duration of time equal to one bit length void initUART(); //Initialize software USART void send_char(unsigned char c); //Transmit a character through software USART
//Bit Delay: A length of time equal to one bit duration at 9600 bps //No timers used, using hardware registers void bit_delay() { //register declaration to maximize and caliberate speed of operation register unsigned char i; for(i=0;i<36;++i) { //Inline assembly code statements occupy precise amount of time asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); } //Additional inline assembly code statements to caliberate the exact //amount of time asm("NOP"); asm("NOP"); }
/**********************************************************************************/
//Initialize software USART by configuring the PORT void PORT_init() { PORTB =0b000000; DDRB =0b001000; // PORTB3 TXD OR PORTB4 RXD }
//Function to transmit a character through software USART /* Baud Rate : 9600 bps Data Bits : 8 Stop Bits : 1 Parity : None Flow Cotrol : None */
void send_char(unsigned char c) // TEST OK { unsigned char i;
//Transmit a start Bit cbi(PORTB,3); bit_delay();
//Transmit the remaining 8 bits for(i=0;i<8;++i) { if((c & 0x01) == 0x01) //Check if LSB is 1 sbi(PORTB,3); //Send a One else //Otherwise cbi(PORTB,3); //Send a 0 bit_delay(); //Wait for one bit length c = c >> 1; //Right Shift the bits so that the //next bit to be transmitted becomes LSB }
sbi(PORTB,3); //Byte Delay for(i=0;i<25;i++) bit_delay(); }
/***************************************/
int get_char(void) // DO NOT TEST { unsigned char n; unsigned int ch;
//while(!PINB4) break; bit_delay(); if (PINB4) return (-1); // or other value, error for ( n = 8, ch = 0 ; n ; --n ) { bit_delay(); bit_delay(); ch >>= 1; if (PINB4) ch += 0x80; } bit_delay(); bit_delay(); if (!PINB4) return (-1); // or other value, error bit_delay(); // wait for end of stop bit send_char(ch); return((unsigned int) ch); //received char }
/***************************************/ void send_string(char *p) { char rd; while(rd = *p++) send_char(rd); }
/**********************************************************************************/
//The main function int main(void) { unsigned char i,key;
PORT_init(); for(i=0;i<100;i++); send_string("Welcome to Sonsivri!!!\r\n"); for(i=0;i<100;i++); while(1) { key = get_char(); switch(key) { case 0x0d: send_string("\r\n"); send_string("\r\n>"); break; case '?': send_string("\r\n"); break; case '1': send_string("test1\r\n>"); break; case '2': send_string("test2\r\n>"); break; default : break; } } return 0; //Never executed }
|
|
|
Logged
|
|
|
|
sabyes
Inactive
Offline
Posts: 4
Thank You
-Given: 0
-Receive: 0
|
|
« Reply #5 on: April 30, 2008, 04:57:56 04:57 » |
|
Cool, I will test it. I try to do this long time ago and I don't know how to start with.
|
|
|
Logged
|
|
|
|
pickit2
Moderator
Hero Member
Offline
Posts: 4658
Thank You
-Given: 832
-Receive: 4301
There is no evidence that I muted SoNsIvRi
|
|
« Reply #6 on: September 21, 2014, 05:42:11 17:42 » |
|
Cool, I will test it. I try to do this long time ago and I don't know how to start with.
I see this was your Last Post in Forum. Today I see you log-in, so now its truly your last post here, until system clock resets to 1905 http://www.sonsivri.to/forum/index.php?action=profile;u=14236;sa=summary
|
|
|
Logged
|
Note: I stoped Muteing bad members OK I now put thier account in sleep mode
|
|
|
gan_canny
Junior Member
Offline
Posts: 89
Thank You
-Given: 101
-Receive: 26
|
|
« Reply #7 on: September 21, 2014, 06:52:21 18:52 » |
|
RS232 is asynchronous and this feature is very important with a software UART. Asynchronous means a character can and will arrive at anytime. Any bit in the character must be caught before the next bit arrives. The time available to catch a bit is determined by the baud rate. So the software loop must complete within approx one half the bit time. Depending on the speed of the processor either very little or just a little amount of processing can be done within the loop. This means since chars arrive asynchronously many CPU cycles are wasted preparing for bits that could have arrived but didn't. Only in specific situations is a software UART a reasonable solution. Most chips will have a hardware UART and interrupt logic. Not using the interrupt with a hardware UART can be wasteful since the loop timing is still heavily restricted.
|
|
|
Logged
|
|
|
|
|