Jump to content

ra68gi

EstablishedMember
  • Content Count

    229
  • Joined

  • Last visited

Everything posted by ra68gi

  1. I got it to compile but it failed to build. My target chip is PIC16F84A & crystal freq is 4MHZ. any help appreciated. Baud rate used 2400. #include <system.h> #pragma CLOCK_FREQ 4000000 // config clock to 4mhz. // Set configuration fuse. #pragma DATA _CONFIG, _XT_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF // RAM used by the software USART driver to emulate the equivalent serial hardware registers // Note this section is really just reserving the space. The defines in the subsequent section // overlay these RAM locations unsigned short sw_SPBRG@0x47; // define location for the emulated SSPCON1 unsigned short sw_RCREG@0x48; // define location for the emulated SSPCON2 unsigned short sw_TXREG@0x49; // define location for the emulated SSPSTAT unsigned short sw_TXSTA@0x4A; // define location for the emulated SSPBUF unsigned short sw_RCSTA@0x4B; // define location for the emulated SSPADD unsigned short sw_TXIF_PIR@0x4C;// define location for the emulated TXIF_PIR1 unsigned short sw_RCIF_PIR@0x4C;// define location for the emulated RCIF_PIR1 // variables cannot be passed as template arguments. The following constants map to // the PIC registers and software emulated USART RAM locations. These constants are // then used by the templated functions. When changing the address of an emulated // register the corresponding constant mapping must also be changed. // Sample PIC16F defaults for software emulated USART support #define TX_PORT 0x06 #define TX_TRIS 0x85 #define TX_BIT 6 #define RX_PORT 0x06 #define RX_TRIS 0x85 #define RX_BIT 7 #define e_SPBRG 0x99 #define e_RCREG 0x1a #define e_TXREG 0x019 #define e_TXSTA 0x98 #define e_RCSTA 0x18 #define e_TXIF_PIR 0x0c #define e_RCIF_PIR 0x0c #define e_TXIF_BIT 4 #define e_RCIF_BIT 5 #define MODE (USART_reset_wdt) // bit_time = FOSC / 4 / BAUDRATE #define bit_time 416 // for 2400bauds with 4mhz crystal #include <rs232_driver.h> void main() { // for the hardware UART the paramter passed is the divisor // the hardware usart enables dynamic reconfiguration of the baud rate // the software emulated USART baud rate is defined by constants in // serial_driver.h - this file also contains the address mapping for // RAM required to support the software emulated USART uart_init(0,21); // 1 for high speed divisor mode and divisor value puts("Hello, world"); while (1) { if (kbhit()) { putc(getc()); } } } Is uart_init() function required for software usart? Raghunathan. error reported.. Building... BoostC Optimizing C Compiler Version 6.60 (for PIC16 architecture) http://www.sourceboost.com Copyright(C) 2004-2006 Pavel Baranov Copyright(C) 2004-2006 David Hobday Single user Lite License (Unregistered) for 0 node(s) Limitations: PIC12,PIC16 max code size:2048 words, max RAM banks:2, Non commercial use only rs232.test1.c success BoostLink Optimizing Linker Version 6.60 http://www.sourceboost.com Copyright(C) 2004-2006 Pavel Baranov Copyright(C) 2004-2006 David Hobday Failure Error: Unable to successfully create 'delay_us' for target with clock freq 4000000 Hz Error: Unavailable timing functions used! "D:\Program Files\SourceBoost\boostc.pic16.exe" rs232.test1.c -t PIC16F84A "D:\Program Files\SourceBoost\boostlink.pic.exe" /ld "D:\Program Files\SourceBoost\lib" libc.pic16.lib rs232.test1.obj /t PIC16F84A /d "D:\Program Files\SourceBoost\Samples\C\BoostC\my test files" /p rs232.test1 Exit code was -2. Removing target: rs232.test1.hex Failed to locate output file 'D:\Program Files\SourceBoost\Samples\C\BoostC\my test files\rs232.test1.hex' Done Failed
  2. It took me a while to understand that these hardware registers are implemented in the RAM locations.& i had to include.... // RAM used by the software USART driver to emulate the equivalent serial hardware registers // Note this section is really just reserving the space. The defines in the subsequent section // overlay these RAM locations unsigned short sw_SPBRG@0x47; // define location for the emulated SSPCON1 unsigned short sw_RCREG@0x48; // define location for the emulated SSPCON2 unsigned short sw_TXREG@0x49; // define location for the emulated SSPSTAT unsigned short sw_TXSTA@0x4A; // define location for the emulated SSPBUF unsigned short sw_RCSTA@0x4B; // define location for the emulated SSPADD unsigned short sw_TXIF_PIR@0x4C;// define location for the emulated TXIF_PIR1 unsigned short sw_RCIF_PIR@0x4C;// define location for the emulated RCIF_PIR1 Regards Raghunathan.
  3. Can i not implement software usart on pic16 chips which doesn't have baud rate generator register(SPBRG), say PIC16F84 ? Raghunathan.
  4. you need to add these lines to your code. void main() { trisb=0; //initialize the port as output port. portb=0; //make all output portb pins low char x; //declare x as character to be used in for-loop. while(1) { ....your code } } Hope you have included the system file, the pragma directives & oscillator frequency. Also see in my second code example i have increased the value of x from 30 to 200 in the forward & reverse loops & to 50 for the turns, so that your robot will traverse thro' a reasonable distance. The for-loop value x will decide the duration for which your servo will rotate in a particular direction. you can put any reasonable value you want. In a practical robot circuit you can have the for- loop just for reverse and turning alone. The code would look more like .. while(1) { if(object detected) { reverse: for(x=0;x<?;x++) { ...; ...; } turn_right_or_left: for(x=0;x<?;x++) { .....; ........; } } else { forward: ...; ......; } } Raghunathan.
  5. while(1) { forward: for(x=0;x<200;x++) { portb.0=1; //right servo control delay_ms(1); portb.0=0; portb.1=1; //left servo control delay_ms(2); portb.1=0; delay_ms(18); } turn_left: for(x=0;x<50;x++) { portb.0=1; delay_10us(150); portb.0=0; portb.1=1; delay_ms(2); portb.1=0; delay_ms(18); } turn_right: for(x=0;x<50;x++) { portb.0=1; delay_ms(1); portb.0=0; portb.1=1; delay_10us(150); portb.1=0; delay_ms(18); } reverse: for(x=0;x<200;x++) { portb.0=1; delay_ms(2); portb.0=0; portb.1=1; delay_ms(1); portb.1=0; delay_ms(18); } } Note: no two servos are similar, say value 150 may or may not cause it to halt. You need to adjust it around this value say, 155 or 145 untill the sero stalls. Similarly the turning speed can be altered by changing the value of the drive from 150 to say 165 or 135. Just try with various value & see the path traced by it. Raghunathan
  6. Can any one tell me which timer is used to generate the baud rate for the software uart? If i use both timer0 and timer1 for other timing application can i still use rs232 communication? Raghunathan.
  7. Why don't you try some thing like, if( var.8==0) or say if(var.15!=1). Raghunathan.
  8. systemchaos, I think you are using a continious rotation servo motor for your robot. As allanlane5 says , a pulse train of 1ms pulse width at a frequency of around 50Hz will cause your sero to rotate in clockwise & a 2ms pulse width at a repetative frequency of 50Hz will cause it to rotate in counter clockwise. & 1.5 ms pulse train will cause it to halt. Now you can do this using the delay_ms(1), delay_ms(2) & delays_100us(15). delay_100us(15) will give you a delay of 1500us which is equal to 1.5ms. A simple code to rotate your servo in back & forth will look like this.. while(1) { clockwise: for(x=0;x<30;x++) // send a pulse train { portb.0=1; delay_ms(1); //1ms pulse width portb.0=0; delay_ms(18); //at a periodicity of around 50hz } anticlockwise: for(x=0;x<30;x++) { portb.0=1; delay_ms(2); //2ms pulse width portb.0=0; delay_ms(18); //at a periodicity of around 50hz } } Try this code & check to see if your servo is working. If most of the other functions like object detection etc takes less then 1ms, you can interlace it with the drive command without changing the performance of the servo. It works fine from 47 hz to 62hz. If you still require to do more time consuming tasks then you can use the timer interrupts to do your timing requirements. There is no need to use the pwm. Raghunathan.
  9. You can also use bit operator ~. signal = ~signal; Regards Raghunathan.
  10. Dave, This is my modified code. #include <system.h> #include <float.h> #include "lcd_driver.h" #pragma CLOCK_FREQ 4000000 // config clock to 4mhz. // Set configuration fuse #pragma DATA _CONFIG, _XT_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF #define LCD_ARGS 1, /* Interface type: mode 0 = 8bit, 1 = 4bit(low nibble), 2 = 4bit(upper nibble) */ \ 0, /* Use busy signal: 1 = use busy, 0 = use time delays */\ PORTC, TRISC, /* Data port and data port tris register */ \ PORTB, TRISB, /* Control port and control port tris register */ \ 2, /* Bit number of control port is connected to RS */ \ 7, /* Bit number of control port is connected to RW */ \ 3 /* Bit number of control port is connected to Enable */ void lprint_float(float x) { x=float32_mul(x,10000); int xi=float32_to_int32(x); int xn=xi/10000; int xd=xi%10000; lprintf("%d",xn); lprintf("%d",xd); } float CalcCircleArea( float radius ) { // area of circule = 2 * pi * (radius^2) // initiall x holds the radius float x; x = float32_mul( radius, radius ); x = float32_mul( x, 3.1415927 ); return x; } void main() { // calc area of a circle // area = pi * r * r float area = CalcCircleArea( 21.75 ); int iArea = float32_to_int32( area ); lcd_setup(); lcd_clear(); lprint_float(area); while( 1 ); } On build i get the following error. "D:\Program Files\SourceBoost\boostc.pic16.exe" -t PIC16F72 float_lcd_test.c BoostC Optimizing C Compiler Version 6.60 (for PIC16 architecture) http://www.sourceboost.com Copyright© 2004-2006 Pavel Baranov Copyright© 2004-2006 David Hobday Single user Lite License (Unregistered) for 0 node(s) Limitations: PIC12,PIC16 max code size:2048 words, max RAM banks:2, Non commercial use only float_lcd_test.c failure D:\Program Files\SourceBoost\include\lcd_driver.h(371): error: missing right paren Failed to locate output file 'float_lcd_test.obj' Done Failed Raghunathan. To check if my lcd section of the code is working i made a seperate code without fp. see code below. It compiles & builds fine. #include <system.h> #include "lcd_driver.h" #pragma CLOCK_FREQ 4000000 #pragma DATA _CONFIG, _XT_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF #define LCD_ARGS 1, /* Interface type: mode 0 = 8bit, 1 = 4bit(low nibble), 2 = 4bit(upper nibble) */ \ 0, /* Use busy signal: 1 = use busy, 0 = use time delays */\ PORTC, TRISC, /* Data port and data port tris register */ \ PORTB, TRISB, /* Control port and control port tris register */ \ 2, /* Bit number of control port is connected to RS */ \ 7, /* Bit number of control port is connected to RW */ \ 3 /* Bit number of control port is connected to Enable */ void main() { unsigned char b0; lcd_setup(); lcd_clear(); lprintf("4Bit test :-)"); lcd_gotoxy(0,1); while(1) { for(b0=0;b0<256;b0++) { lcd_clear(); lprintf("%d",b0); delay_s(1); } } } Why does it not compile with fp. Is it because iam using the free lite version & my code exceeds 2k?
  11. Dave, I know that BoostC automatically takes care of the 2k page boundry by setting the pclatch bits. I have a doubt. If i include all the BoostC library ( fp etc) & if the lib itself takes more space ( exceeds page0 ) ( over and above this if we have to accomodate interrupt at the beginning of the code) will the compiler have trouble? If so what precautions should i take. Raghunathan.
  12. How do i display variables on LCD? Iam using Daves fp example program. My code doesn't work. #include <system.h> #include <float.h> #include "lcd_driver.h" #pragma CLOCK_FREQ 4000000 // config clock to 4mhz. // Set configuration fuse #pragma DATA _CONFIG, _XT_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF #define LCD_ARGS 1, /* Interface type: mode 0 = 8bit, 1 = 4bit(low nibble), 2 = 4bit(upper nibble) */ \ 0, /* Use busy signal: 1 = use busy, 0 = use time delays */\ PORTA, TRISA, /* Data port and data port tris register */ \ PORTB, TRISB, /* Control port and control port tris register */ \ 2, /* Bit number of control port is connected to RS */ \ 7, /* Bit number of control port is connected to RW */ \ 3 /* Bit number of control port is connected to Enable */ float CalcCircleArea( float radius ) { // area of circule = 2 * pi * (radius^2) // initiall x holds the radius float x; x = float32_mul( radius, radius ); x = float32_mul( x, 3.1415927 ); return x; } void main() { // calc area of a circle // area = pi * r * r float area = CalcCircleArea( 21.75 ); int iArea = float32_to_int32( area ); lcd_setup(); lcd_clear(); lprintf("area = ",float area ); while( 1 ); } Raghunathan
  13. Thanks, those words of assurance make me more happy that i can work with pics.
  14. Dave, its important for me to have fp in many of my projects. I have used fp in 8051 core using bascom compiler. The problem with atmel At89c8051 series of chips don't have a/d converters so i wanted to use pic. Bascom has data type single for fp. Just for your information let me show a sample code in basic which take just 1829 words of program memory to display RPM/ frequency on a lcd. Dim Count As Word Dim F0 As Byte Dim F1 As Byte Dim Z As Long Dim Rpm As Single Dim Update_freq As Bit $regfile = "89C2051.DAT" $crystal = 12000000 Config Timer0 = Timer , Mode = 1 , Gate = Internal Config Timer1 = Counter , Mode = 2 , Gate = Internal On Timer0 Timer0_int On Timer1 Timer1_int Priority Set Timer1 Enable Interrupts Enable Timer0 Enable Timer1 Load Timer1 , 1 Begin: Gosub Banner F0 = 0 : Count = 0 : F1 = 0 : Update_freq = 1 Main: Do If Update_freq = 1 Then Update_freq = 0 Z = F0 F0 = 0 Z = Z * 65536 Z = Z + Count If Z = 0 Then Rpm = 0 Gosub Disply Else Z = 100000000 / Z Z = Z * 60 Rpm = Z / 100 Gosub Disply End If End If Loop Timer0_int: Incr F0 If F0 > 15 Then Stop Timer0 Stop Timer1 F0 = 0 : Count = 0 : Update_freq = 1 End If Return Timer1_int: Count = Counter0 Counter0 = 10 Start Timer0 P1.0 = Not P1.0 Incr F1 If F1 > 1 Then Stop Timer0 Stop Timer1 F1 = 0 Update_freq = 1 End If Return Disply: Cls Lcd " RPM = "; Rpm Waitms 2 Waitms 2 Waitms 1 Counter0 = 0 Start Timer0 Start Timer1 Return Banner: Cls Lcd " MICRO ENERGY" Waitms 2 Return A small bit of information regarding the bascom floating point. Floating point Single numbers conform to the IEEE binary floating point standard. An eight-bit exponent and 24 bit mantissa are supported. Using four bytes, the format is shown below: 31 30________23 22______________________________0 s....exponent.....mantissa The exponent is biased by 128. Above 128 are positive exponents and below are negative. The sign bit is 0 for positive numbers and 1 for negative. The mantissa is stored in hidden bit normalized format so that 24 bits of precision can be obtained. All mathematical operations are supported by the single. You can also convert a single to an integer or word or vise versa: Dim I as Integer, S as Single S = 100.1 'assign the single I = S 'will convert the single to an integer any other suggestions? Raghunathan.
  15. Hi Dave, I just may not be able to use fp because the above code ( area of circle) alone takes 1206 words of program memory & 74 bytes of RAM. Is there any way out for a more compact code? Raghunathan.
  16. Do you mean #include <float.pic16.lib> ? I really don't know how to add the file. Raghunathan. With the above include it gives me error again. Raghunathan. <{POST_SNAPBACK}> Yes i got it. I selected the projects in the IDE tool bar and clicked add files & then added float.pic16.lib. It builds. Can not the .h file automatically add the lib file like in the lcd commands? Thanks Raghunathan
  17. Do you mean #include <float.pic16.lib> ? I really don't know how to add the file. Raghunathan. With the above include it gives me error again. Raghunathan.
  18. Hi Guys, The code example given by Dave ( area of circle ) compiles successfully but when i build, I get errors. any Reason? I have float.pic16 & float.pic18 loaded in my .lib folder, & also the float.h file in the include folder. #include <system.h> #include <float.h> #pragma CLOCK_FREQ 4000000 // config clock to 4mhz. // Set configuration fuse #pragma DATA _CONFIG, _XT_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF float CalcCircleArea( float radius ) { // area of circule = 2 * pi * (radius^2) // initiall x holds the radius float x; x = float32_mul( radius, radius ); x = float32_mul( x, 3.1415927 ); return x; } void main() { // calc area of a circle // area = pi * r * r float area = CalcCircleArea( 21.75 ); int iArea = float32_to_int32( area ); while( 1 ); } It shows the following error while build. Building... BoostLink Optimizing Linker Version 6.60 http://www.sourceboost.com Copyright© 2004-2006 Pavel Baranov Copyright© 2004-2006 David Hobday Failure Error: Unresolved external function:'float32_mul(float,float)' Error: Unresolved external function:'float32_mul(float,float)' Error: Unresolved external function:'float32_mul(float,float)' Error: Unresolved external function:'float32_mul(float,float)' Error: Unresolved external function:'float32_mul(float,float)' Error: Unresolved external function:'float32_mul(float,float)' Error: Unresolved external function:'float32_mul(float,float)' Error: Unresolved external function:'float32_mul(float,float)' Error: Unresolved external function:'float32_mul(float,float)' Error: Unresolved external function:'float32_mul(float,float)' Error: Unresolved external function:'float32_mul(float,float)' Error: Unresolved external function:'float32_mul(float,float)' Error: Unresolved external function:'float32_mul(float,float)' Error: Unresolved external function:'float32_mul(float,float)' Error: Unresolved external function:'float32_mul(float,float)' Error: Unresolved external function:'float32_mul(float,float)' Error: Unresolved external function:'float32_mul(float,float)' Error: Unresolved external function:'float32_mul(float,float)' Error: Unresolved external function:'float32_mul(float,float)' Error: Unresolved external function:'float32_mul(float,float)' Error: Unresolved external function:'float32_to_int32(float)' Error: Unresolved external function:'float32_to_int32(float)' Error: Unresolved external function:'float32_to_int32(float)' Error: Unresolved external function:'float32_to_int32(float)' Error: Unresolved external function:'float32_to_int32(float)' Error: Unresolved external function:'float32_mul(float,float)' Error: Unresolved external symbol, function:float32_mul Error: Unresolved external function:'float32_mul(float,float)' Error: Unresolved external symbol, function:float32_mul Error: Unresolved external function:'float32_to_int32(float)' Error: Unresolved external symbol, function:float32_to_int32 "D:\Program Files\SourceBoost\boostlink.pic.exe" /ld "D:\Program Files\SourceBoost\lib" libc.pic16.lib float_test1.obj /t PIC16F72 /d "D:\Program Files\SourceBoost\Samples\C\BoostC\my test files" /p float_test1 Exit code was -2. Removing target: float_test1.hex Failed to locate output file 'D:\Program Files\SourceBoost\Samples\C\BoostC\my test files\float_test1.hex' Done Failed Raghunathan.
  19. Hi guys, If i don't use the write option in the lcd and don't want to assign any pin ( conserve the pin for other purpose) what do i write in #LCD_ARGS 1, \ 0, \ porta,trisa, \ portb,trisb, \ 2, \ ?, \ 3, Is it not possible to have control bits from different ports? Raghunathan.
  20. Well it seems correct to me that n should equal 1 for a count sequence of 256 states. Consider this, TMR0 has just counted from 0xFF to 0x00, the TMR0IF flag is set. Is TMR0 at the terminal state or at the initial state? You only get to pick one. If it's at the terminal state then logically the next state (0x01) would be the initial state for a count cycle of 256 clocks. I don't know but my reasoning seems correct, but I could be wrong. Do you have a better way to explain the TMR0 works? cac. <{POST_SNAPBACK}> Hi cac, I thought you would have solved the problem and infact i was very anxiously waiting for your reponse. My reasoning turned out to be right. ie. it take 3 clock cycles for the timer0 to start running. 1st clock cycle to write onto tmr0 and another 2 clock cycles of inhibition after the write operation. I changed the code to tmr0+=0; and tried it on the mplab sim with a stop watch. But when i set the break point & made it run, it did not stop. I didn't know why. So i made another variable by name check initialized to 0 & added to it. ie. tmr0+=check; & checked it up. I got 259,518,1036,1295,1554... some times i got +- one cycle but got corrected the next run. I found one more thing, writing tmr0 value to tmr0 itself causes 4 cycles dealy.ie. tmr0=tmr0;. I got 260,520,780,1041,1300,1559,1820.... Raghunathan.
  21. You arrived at the correct number but for the wrong reason. This has to do with the way we count with integers. Try this exercise: Using a 8-bit HEX representation for numbers count backwards until you have written five numbers. Take that fifth number and make a 2's complement of it. What is that number? 0x00 number 1 0xFF number 2 0xFE number 3 0xFD number 4 0xFC number 5 (0xFC ^ 0xFF) + 1 = 4 -------------------------- Try thinking of TMR0 as counting from 1 to 256. Then ask what number (n) needs to be in TMR0 such that there are 250 numbers from (n) to 256 including both (n) and 256? Answer: n = 256 - 250 + 1, or 7 Each one of the 250 numbers represents a count state of TMR0. To correct for the 2-clock delay after a write to TMR0 we add 2 to n. This give us a final working value of n = 9. cac. <{POST_SNAPBACK}> So your equation boils down to n=(256-x) +1; Let's see if your equation is consistent. If x=256 then n=(256-256) + 1; n=1; So if we leave the tmr0 to count upto 256 we need to make n= 1 & thats wrong. A formula should be consistent for all value 0<x <=256. Regards Raghunathan.
  22. Guys, Let me type whats written on to the data sheet again. It says, If tmr0 register is written, the increment is inhibited for the following two instruction cycles. The user can work around this by writing an adjusted value to the tmr0 register. For the 1st clock cycle the write operation takes place. For the next two clock cycles the timer is inhibited. So in total the counter is inactive for three clock cycles. So looks like we need to add 3 to 6 and write it as tmr0+=9;. Some reverse engineering i guess. Please comment.
  23. ra68gi, I have run your code using the MPLAB simulator. After changing line 38 from "tmr0 +=2;" to "tmr0 +=8;" I set a break point at line 38. Executed the code until the break point is reached. Opened the Stopwatch dialog and zeroed the time. Then I press F9 to run until the break point is reached four times. The expected cycle count should be 1000. It is in fact 1004. If you keep pressing F9 the cycle count gap between the expected and actual keeps getting larger. So this is not an interrupt latency issue. The adjustment to the TMR0 period is not correct. One of us must be wrong. I think it may be you. cac. <{POST_SNAPBACK}> Special thanks to you cac. You have been so patient & helpful in sorting out the tmr0 issue. I too tested it on the simulator and found the same error. When i changed it to tmr0+=9; it gave perfect result. Occasionally it shows one micosecond less or more but it gets corrected in the next run. some of the values i got are 250,500,750,1001,1250,1500......4501,4750....,6749,7000.... Looks like its self adjusting. But how am i going to justify tmr0+=9;. It defies my logic. cac, trossin, dave, any one who can give an explaination? note- 1 count error in one interrupt cycle will results in 4000 count per second & around 5.76 minutes per day.
  24. But that will be a all together different project. Regards, Raghunathan.
×
×
  • Create New...