|
|
View previous topic :: View next topic |
Author |
Message |
naughty_mark
Joined: 29 Aug 2012 Posts: 97
|
dsPIC33 system clock setting question |
Posted: Tue Sep 11, 2012 6:19 pm |
|
|
Hi, guys.
Yesterday, I got my bootloader code running, however, it can only work under 2400 baudrate, any baudrate higher than it will not work. Maybe the code structure not good enough.
I would like to increase the system clock speed to achieve higher baudrate.
Originally, my fuse statement is
Code: |
#if defined(__PCD__)
#include <33EP256MU814.h>
#fuses HS,PR,NOWDT,ICSP2,NOGSSK,NOPROTECT,NOAPROTECT,NOAPLK
#device ADC=12
#use delay(clock=20000000)
#pin_select U1TX = PIN_D0
#pin_select U1RX = PIN_D1
#pin_select U2TX = PIN_D2
#pin_select U2RX = PIN_D3
#use RS232(UART1, STREAM = GSM, BAUD=2400, XMIT = PIN_D0 , RCV = PIN_D1 , BITS = 8, STOP = 1, PARITY = N, ERRORS) // Actual Baud is 38400 due to clock (10M not 20M)
#use RS232(UART2, STREAM = MODBUS, BAUD=9600, XMIT = PIN_D2 , RCV = PIN_D3 , BITS = 8, STOP = 1, PARITY = N, ERRORS)
#use i2c(MASTER, I2C1,SCL = PIN_D10, SDA = PIN_D9 , FORCE_SW)
#pin_select IC1=PIN_F0
#pin_select C1TX = PIN_D6
#pin_select C1RX = PIN_D5
#endif
|
As my understanding, I only need to change #use delay(clock=20000000) to #use delay(clock=80000000), then the ccs will config the PLL and give me Fosc as 80MHZ, am I right? However, after I changed that, the bootloader can not receive data via RS232 correctly, even under 2400 baudrate! Is there anything I didn't do right?
EDIT: I am using 20M external crystal osc
Thanks a lot
Kind Regards
Mark |
|
|
naughty_mark
Joined: 29 Aug 2012 Posts: 97
|
|
Posted: Thu Sep 13, 2012 7:27 pm |
|
|
EDIT: sorry guys, wrong post~ looks it can give me fast system clock. but the register value looks weird
I tried this way
Code: |
#if defined(__PCD__)
#include <33EP256MU814.h>
//#include <i2c.h>
#fuses HS,PR,NOWDT,ICSP2,NOGSSK,NOPROTECT,NOAPROTECT,NOAPLK,PR_PLL
//#build(reset = 0x7FFFFFE, interrupt = 0x7FFFFFA)
//CKSFSM -enable oscillator clock switching mode when a OSC failure has occurred.
//#build (stack=256)
//#build (stack=0x1E00:0x1FFF)
#device ADC=12
//#use delay(clock=20000000) // Actual crystal is 20M
#use delay(clock=80M, xtal=20M) // Actual crystal is 20M
#pin_select U1TX = PIN_D0
#pin_select U1RX = PIN_D1
#pin_select U2TX = PIN_D2
#pin_select U2RX = PIN_D3
#use RS232(UART1, STREAM = GSM, BAUD=2400, XMIT = PIN_D0 , RCV = PIN_D1 , BITS = 8, STOP = 1, PARITY = N, ERRORS) // Actual Baud is 38400 due to clock (10M not 20M)
#use RS232(UART2, STREAM = MODBUS, BAUD=9600, XMIT = PIN_D2 , RCV = PIN_D3 , BITS = 8, STOP = 1, PARITY = N, ERRORS) // Actual Baud is 38400 due to clock (10M not 20M)
//#use spi(MASTER, DO = PIN_G8, CLK = PIN_G6, mode = 3, stream=SPI_STREAM)
#use i2c(MASTER, I2C1,SCL = PIN_D10, SDA = PIN_D9 , FORCE_SW)
#pin_select IC1=PIN_F0
#pin_select C1TX = PIN_D6
#pin_select C1RX = PIN_D5
//#include <pcd_bootloader.h>
#endif
|
However, when I debug it. the relevant register value is weird.
PLLFBD = 0x0016
CLKDIV = 0x0001
OSCCON = 0x3320
which means
PLL DIV = 24
PLLPRE = 3
PLLPOST = 2
and according to the formula
Fosc = Fin * (PLLDIV +2)/((PLLPRE+2) * 2*(PLLPOST+1))
that can not give me 80MHZ system clock, even lower than 20M, anyideas?
Thanks a lot |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1358
|
|
Posted: Thu Sep 13, 2012 8:04 pm |
|
|
You are using two mutually exclusive fuses (PR and PR_PLL). I don't know if that is causing your problem, but you should be using PR_PLL only.
EDIT: also, I think you are confusing actual register values with what they represent. Don't use the values in the text in the math, use the actual register values in the math.
PLLPRE =1 => 1+2 = 3 = N1
PLLPOST=0 => 2*(0+1) = 2 = N2
PLLDIV=0x16 => 22+2 = 24 = M
FOSC = FIN*(24/(2*3)) = 4*FIN
So FIN=20 => FOSC=80
It works out correctly.
EDIT2: You should take a look at the baud rate registers to see if those are being calculated correctly. Some of the 16 bit pic did have some UART hardware bugs as well, so check errata for your chip to make sure there aren't any problems to look for.
EDIT3:
And remember, you can always test your clock with a simple main:
Code: |
void main(void){
while(TRUE){
delay_ms(500);
output_toggle(PIN_XX); //change this to whatever pin you want to scope
}
}
|
Toss it on an oscilloscope and see if the line toggles every 500ms (or 1HZ square wave). If not your clock is off. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|