//****************************************************************************************** // PIC18F14K50 Sample Program // Project : // Program Name : // Programer : // Create date : Version 1.0 H24.11.25 // History : // Laungage : MPLAB C18 //****************************************************************************************** // (1)Description // //****************************************************************************************** #include #include #include #include #include #include #include #include #include //config words #pragma config CPUDIV=NOCLKDIV //CPU System Clock Selection bit(No CPU System Clock divide) #pragma config USBDIV = OFF //USB Clock Selection bit(USB Clock comes directly from the OSC1/OSC2 oscillator block; no divide) //#pragma config FOSC = HS //Oscillator Selection bits(HS oscillator) #pragma config FOSC = IRC //Oscillator Selection bits(Internal RC oscillator) #pragma config PLLEN = ON //X PLL Enable bit(Oscillator multiplied by 4) #pragma config PCLKEN = OFF //Primary Clock Enable Bit(Primary clock is under software control) #pragma config FCMEN = OFF #pragma config IESO = OFF //Internal/External Oscillator Switchover bit(Oscillator Switchover mode disabled) #pragma config PWRTEN = OFF,BOREN = OFF,BORV = 19 #pragma config WDTEN = OFF,WDTPS = 1 #pragma config MCLRE = OFF //MCLR Pin Enable bit(RE3 input pin enabled; MCLR disabled) #pragma config HFOFST = OFF,STVREN = OFF,LVP = OFF,BBSIZ = OFF,XINST = OFF #pragma config CP0 = OFF,CP1 = OFF,CPB = OFF,CPD = OFF,WRT0 = OFF,WRT1 = OFF,WRTB = OFF,WRTC = OFF,WRTD = OFF,EBTR0 = OFF,EBTR1 = OFF,EBTRB = OFF void InitOSC(void); void Init_I2C(void); void SETPWM(unsigned char, unsigned char, unsigned int, unsigned char); void Write_DRV8830( unsigned char, unsigned char, unsigned char ); void InitUART(void); void SendUART(char); void ReciveUART(char *); void SendUART_s(char *); void Get_data(unsigned int *, unsigned char *); #define PI_MINUS 0 #define PI_PLUS 1 void main(void) { unsigned char SLV_ADDR = 0xC0; unsigned char SUB_ADDR = 0x00; unsigned int pwm_data = 0x00; unsigned char sign = PI_PLUS; unsigned char tmp_char; unsigned char Msg_1[] = " PIC18F14K50 Connected OK> "; unsigned char Msg_2[] = " Command format : (+nn/-nn) 00<=nn<100 "; unsigned char Msg_3[] = " [OK] "; // ***************************** // 1.Initialized Segment // ***************************** // (1)Define OSC InitOSC(); //Internal OSC 16MHz // (2)Define I/O port PORTA = 0x00; PORTB = 0x00; PORTC = 0x00; TRISA = 0b11111111; TRISB = 0b11111111; TRISC = 0b11111111; // (3)Define MSSP Init_I2C(); // (4)Initialize USART InitUART(); // (5)Demo Massage SendUART_s(Msg_1); SendUART_s(Msg_2); // ***************************** // 2.Program main // ***************************** while(1){ // (1)Get UART data Get_data(&pwm_data, &sign); // (2)Put Message SendUART_s(Msg_3); // (3)Put I2C SETPWM(SLV_ADDR, SUB_ADDR, pwm_data, sign); } } //****************************************************************************************** // Function Name : Get_data // Title : // Input : // Output : // Description : //****************************************************************************************** void Get_data(unsigned int *pwm_data, unsigned char *sign) { unsigned char tmp_char; // ************* // 1.Set Sign // ************* while(1){ ReciveUART(&tmp_char); if(tmp_char=='+'){ *sign = PI_PLUS ; break; }else if(tmp_char=='-'){ *sign = PI_MINUS ; break; } } SendUART(tmp_char); // ************* // 2.Set Numeric // ************* while(1){ ReciveUART(&tmp_char); if(('0' <= tmp_char) && ( tmp_char <= '9')){ *pwm_data = ( tmp_char & 0x0f ) * 10; break; } } SendUART(tmp_char); while(1){ ReciveUART(&tmp_char); if(('0' <= tmp_char) && ( tmp_char <= '9')){ *pwm_data = *pwm_data + ( tmp_char & 0x0f ); break; } } SendUART(tmp_char); } //****************************************************************************************** // Function Name : SETPWM // Title : // Input : // Output : // Description : //****************************************************************************************** void SETPWM(unsigned char SLV_ADDR, unsigned char SUB_ADDR, unsigned int pwm_data, unsigned char sign) { unsigned char I2C_DATA; // *************************** // 1.Initialize data // *************************** // (1)Convert parcent-data to I2C-data if(pwm_data > 100) pwm_data = 100; pwm_data = pwm_data * 0x3f / 100 ; if(pwm_data > 0x3f) pwm_data = 0x3f; // (2)Add sign if(pwm_data < 0x06){ I2C_DATA = ( 0x06 << 2 ) | 0b00000000; }else if(sign == PI_PLUS){ I2C_DATA = ((unsigned char)pwm_data << 2 )| 0b00000001; }else{ I2C_DATA = ((unsigned char)pwm_data << 2 )| 0b00000010; } // *************************** // 2.Write DRV8830 // *************************** Write_DRV8830( SLV_ADDR, SUB_ADDR, I2C_DATA); } //****************************************************************************************** // Function Name : Init_I2C // Title : // Input : // Output : // Description : //****************************************************************************************** void Init_I2C(void) { // ******************************************************* // 1.Define SSPSTAT: MSSP STATUS REGISTER (I2C MODE) // SSPSTAT(7) SMP: Slew Rate Control bit // In Master or Slave mode: // 1 = Slew rate control disabled for standard speed mode (100 kHz and 1 MHz) // 0 = Slew rate control enabled for high-speed mode (400 kHz) // SSPSTAT(6) CKE: SMBus Select bit // In Master or Slave mode: // 1 = Enable SMBus specific inputs // 0 = Disable SMBus specific inputs // SSPSTAT(5) D/A: Data/Address bit // In Master mode: Reserved. // In Slave mode: // 1 = Indicates that the last byte received or transmitted was data // 0 = Indicates that the last byte received was an address // SSPSTAT(4) P: Stop bit(1) // 1 = Indicates that a Stop bit has been detected last // 0 = Stop bit was not detected last // SSPSTAT(3) S: Start bit(1) // 1 = Indicates that a Start bit has been detected last // 0 = Start bit was not detected last // SSPSTAT(2) R/W: Read/Write Information bit (I2C mode only)(2, 3) // In Slave mode: // 1 = Read // 0 = Write // In Master mode: // 1 = Transmit is in progress // 0 = Transmit is not in progress // SSPSTAT(1) UA: Update Address bit (10-bit Slave mode only) // 1 = Indicates that the user needs to update the address in the SSPADD register // 0 = Address does not need to be updated // SSPSTAT(0) BF: Buffer Full Status bit // In Transmit mode: // 1 = SSPBUF is full // 0 = SSPBUF is empty // In Receive mode: // 1 = SSPBUF is full (does not include the ACK and Stop bits) // 0 = SSPBUF is empty (does not include the ACK and Stop bits) // ******************************************************* SSPSTAT = 0b10000000; // ******************************************************* // 2.Define SSPCON1: MSSP CONTROL 1 REGISTER (I2C MODE) // SSPCON1(7) WCOL: Write Collision Detect bit // In Master Transmit mode: // 1 = A write to the SSPBUF register was attempted while the I2C conditions were not valid // for a transmission to be started (must be cleared by software) // 0 = No collision // In Slave Transmit mode: // 1 = The SSPBUF register is written while it is still transmitting the previous word // (must be cleared by software) // 0 = No collision // In Receive mode (Master or Slave modes): This is a gdonft careh bit. // SSPCON1(6) SSPOV: Receive Overflow Indicator bit // In Receive mode: // 1 = A byte is received while the SSPBUF register is still holding the previous byte // (must be cleared by software) // 0 = No overflow // In Transmit mode: This is a gdonft careh bit in Transmit mode. // SSPCON1(5) SSPEN: Synchronous Serial Port Enable bit // 1 = Enables the serial port and configures the SDA and SCL pins as the serial port pins // 0 = Disables serial port and configures these pins as I/O port pins When enabled, the SDA and SCL // pins must be properly configured as inputs. // SSPCON1(4) CKP: SCK Release Control bit // In Slave mode: // 1 = Release clock // 0 = Holds clock low (clock stretch), used to ensure data setup time // In Master mode: Unused in this mode. // SSPCON1(3-0) SSPM<3:0>: Synchronous Serial Port Mode Select bits // 1111 = I2C Slave mode, 10-bit address with Start and Stop bit interrupts enabled // 1110 = I2C Slave mode, 7-bit address with Start and Stop bit interrupts enabled // 1011 = I2C Firmware Controlled Master mode (Slave Idle) // 1000 = I2C Master mode, clock = FOSC/(4 * (SSPADD + 1)) // 0111 = I2C Slave mode, 10-bit address // 0110 = I2C Slave mode, 7-bit address // Bit combinations not specifically listed here are either reserved or implemented in SPI mode only. // ******************************************************* SSPCON1 = 0b00101000; // ******************************************************* // 3.Define SSPCON2: MSSP CONTROL REGISTER (I2C MODE) // SSPCON2(7) GCEN: General Call Enable bit (Slave mode only) // 1 = Generate interrupt when a general call address 0x00 or 00h is received in the SSPSR // 0 = General call address disabled // SSPCON2(6) ACKSTAT: Acknowledge Status bit (Master Transmit mode only) // 1 = Acknowledge was not received from slave // 0 = Acknowledge was received from slave // SSPCON2(5) ACKDT: Acknowledge Data bit (Master Receive mode only)(2) // 1 = Not Acknowledge // 0 = Acknowledge // SSPCON2(4) ACKEN: Acknowledge Sequence Enable bit (Master Receive mode only)(1) // 1 = Initiate Acknowledge sequence on SDA and SCL pins and transmit ACKDT data bit. // Automatically cleared by hardware. // 0 = Acknowledge sequence Idle // SSPCON2(3) RCEN: Receive Enable bit (Master mode only)(1) // 1 = Enables Receive mode for I2C // 0 = Receive Idle // SSPCON2(2) PEN: Stop Condition Enable bit (Master mode only)(1) // 1 = Initiate Stop condition on SDA and SCL pins. Automatically cleared by hardware. // 0 = Stop condition Idle // SSPCON2(1) RSEN: Repeated Start Condition Enable bit (Master mode only)(1) // 1 = Initiate Repeated Start condition on SDA and SCL pins. Automatically cleared by hardware. // 0 = Repeated Start condition Idle // SSPCON2(0) SEN: Start Condition Enable/Stretch Enable bit(1) // In Master mode: // 1 = Initiate Start condition on SDA and SCL pins. Automatically cleared by hardware. // 0 = Start condition Idle // In Slave mode: // 1 = Clock stretching is enabled for both slave transmit and slave receive (stretch enabled) // 0 = Clock stretching is disabled // ******************************************************* SSPADD = 0x27; // Fosc:16MHz, Fcy:4MHz, Fscl:100KHz, SSPADD = ( FOSC / (4 * clock)) - 1 // SSPADD: 16000000 / ( 4 * 100000 ) - 1 ==> 0d39 ==> 0x27 SSPCON2 = 0b00000000; } //****************************************************************************************** // Function Name : Write_DRV8830 // Title : // Input : // Output : // Description : //****************************************************************************************** void Write_DRV8830( unsigned char SLV_ADDR, unsigned char SUB_ADDR, unsigned char DAC_DATA) { // 1.Start Condition IdleI2C(); // ensure module is idle StartI2C(); // initiate START condition while ( SSPCON2bits.SEN ); // wait until start condition is over // 2.Write Slave Address WriteI2C( SLV_ADDR ); IdleI2C(); // 3.Write Sub Address WriteI2C( SUB_ADDR ); IdleI2C(); // 4.Write Data WriteI2C( DAC_DATA ); IdleI2C(); // 5.Stop Condition StopI2C(); // send STOP condition while ( SSPCON2bits.PEN ); // wait until stop condition is over } //****************************************************************************************** // Function Name : InitOSC // Title : // Input : // Output : // Description : Internal 16MHz //****************************************************************************************** void InitOSC(void) { // ******************************************************* // 1.Define OSCCON(OSCILLATOR CONTROL REGISTER) // OSCCON(7) IDLEN: Idle Enable bit // 1 = Device enters Idle mode on SLEEP instruction // 0 = Device enters Sleep mode on SLEEP instruction // OSCCON(6-4) IRCF<2:0>: Internal Oscillator Frequency Select bits // 111 = 16 MHz // 110 = 8 MHz // 101 = 4 MHz // 100 = 2 MHz // 011 = 1 MHz(3) // 010 = 500 kHz // 001 = 250 kHz // 000 = 31 kHz(2) // OSCCON(3) OSTS: Oscillator Start-up Time-out Status bit(1) // 1 = Device is running from the clock defined by FOSC<2:0> of the CONFIG1 register // 0 = Device is running from the internal oscillator (HFINTOSC or LFINTOSC) // OSCCON(2) HFIOFS: HFINTOSC Frequency Stable bit // 1 = HFINTOSC frequency is stable // 0 = HFINTOSC frequency is not stable // OSCCON(1-0) SCS<1:0>: System Clock Select bits // 1x = Internal oscillator block // 01 = Secondary (Timer1) oscillator // 00 = Primary clock (determined by CONFIG1H[FOSC<3:0>]). // ******************************************************* OSCCON =0b11111111; //Internal 16MHz // ******************************************************* // 2.Define OSCCON2(OSCILLATOR CONTROL REGISTER 2) // OSCCON2(7-3) Unimplemented: Read as e0f // OSCCON2(2) PRI_SD: Primary Oscillator Drive Circuit shutdown bit // 1 = Oscillator drive circuit on // 0 = Oscillator drive circuit off (zero power) // OSCCON2(1) HFIOFL: HFINTOSC Frequency Locked bit // 1 = HFINTOSC is in lock // 0 = HFINTOSC has not yet locked // OSCCON2(0) LFIOFS: LFINTOSC Frequency Stable bit // 1 = LFINTOSC is stable // 0 = LFINTOSC is not stable // ******************************************************* OSCCON2 =0b00000000; // ******************************************************* // 3.Define OSCTUNE(OSCILLATOR TUNING REGISTER) // OSCTUNE(7) INTSRC: Internal Oscillator Low-Frequency Source Select bit // 1 = 31.25 kHz device clock derived from 16 MHz HFINTOSC source (divide-by-512 enabled) // 0 = 31 kHz device clock derived directly from LFINTOSC internal oscillator // OSCTUNE(6) SPLLEN: Software Controlled Frequency Multiplier PLL bit // 1 = PLL enabled (for HFINTOSC 8 MHz only) // 0 = PLL disabled // OSCTUNE(5-0) TUN<5:0>: Frequency Tuning bits // 011111 = Maximum frequency // 011110 = // EEEE // 000001 = // 000000 = Oscillator module is running at the factory calibrated frequency. // 111111 = // EEEE // 100000 = Minimum frequency // ******************************************************* OSCTUNE = 0b00000000; } //****************************************************************************************** // Function Name : SendUART_s // Title : // Input : // Output : // Description : Write TXREG //****************************************************************************************** void SendUART_s(char *put_string) { while(*put_string!=0x00){ SendUART(*put_string); put_string++; } } //****************************************************************************************** // Function Name : InitUART // Title : // Input : // Output : // Description : Fosc:48MHz, Baud Rate:9600BPS, 16-bit Baud Rate //****************************************************************************************** void InitUART(void) { // ******************************************************* // 0.Define ANSELH(ANALOG SELECT REGISTER 2) // ANSELH(3) ANS11: RB5 Analog Select Control bit // 0 = Digital input buffer of RB5 is enabled // ******************************************************* ANSELH = ANSELH & 0b11110111; // ******************************************************* // 1.Define TXSTA(TRANSMIT STATUS AND CONTROL) Register // TXSTA(7) CSRC: Clock Source Select bit // Asynchronous mode:Donft care // TXSTA(6) TX9: 9-bit Transmit Enable bit // 1 = Selects 9-bit transmission // 0 = Selects 8-bit transmission // TXSTA(5) TXEN: Transmit Enable bit(1) // 1 = Transmit enabled // 0 = Transmit disabled // TXSTA(4) SYNC: EUSART Mode Select bit // 1 = Synchronous mode // 0 = Asynchronous mode // TXSTA(3) SENDB: Send Break Character bit // Asynchronous mode: // 1 = Send Sync Break on next transmission (cleared by hardware upon completion) // 0 = Sync Break transmission completed // TXSTA(2) BRGH: High Baud Rate Select bit // Asynchronous mode: // 1 = High speed // 0 = Low speed // TXSTA(1) TRMT: Transmit Shift Register Status bit // 1 = TSR empty // 0 = TSR full // TXSTA(0) TX9D: Ninth bit of Transmit Data // Can be address/data bit or a parity bit. // ******************************************************* TXSTA = 0b00100100; // ******************************************************* // 2.Define RCSTA(RECEIVE STATUS AND CONTROL) Register // RCSTA(7) SPEN: Serial Port Enable bit // 1 = Serial port enabled (configures RX/DT and TX/CK pins as serial port pins) // 0 = Serial port disabled (held in Reset) // RCSTA(6) RX9: 9-bit Receive Enable bit // 1 = Selects 9-bit reception // 0 = Selects 8-bit reception // RCSTA(5) SREN: Single Receive Enable bit // Asynchronous mode: // Donft care // RCSTA(4) CREN: Continuous Receive Enable bit // Asynchronous mode: // 1 = Enables receiver // 0 = Disables receiver // RCSTA(3) ADDEN: Address Detect Enable bit // Asynchronous mode 9-bit (RX9 = 1): // 1 = Enables address detection, enable interrupt and load the receive buffer when RSR<8> is set // 0 = Disables address detection, all bytes are received and ninth bit can be used as parity bit // Asynchronous mode 8-bit (RX9 = 0): // Donft care // RCSTA(2) FERR: Framing Error bit // 1 = Framing error (can be updated by reading RCREG register and receive next valid byte) // 0 = No framing error // RCSTA(1) OERR: Overrun Error bit // 1 = Overrun error (can be cleared by clearing bit CREN) // 0 = No overrun error // RCSTA(0) RX9D: Ninth bit of Received Data // This can be address/data bit or a parity bit and must be calculated by user firmware. // ******************************************************* RCSTA=0b10010000; // ******************************************************* // 3.Define BAUDCON(BAUD RATE CONTROL) Register // BAUDCON(7) ABDOVF: Auto-Baud Detect Overflow bit // Asynchronous mode: // 1 = Auto-baud timer overflowed // 0 = Auto-baud timer did not overflow // BAUDCON(6) RCIDL: Receive Idle Flag bit // Asynchronous mode: // 1 = Receiver is Idle // 0 = Start bit has been detected and the receiver is active // BAUDCON(5) DTRXP: Data/Receive Polarity Select bit // Asynchronous mode: // 1 = Receive data (RX) is inverted (active-low) // 0 = Receive data (RX) is not inverted (active-high) // BAUDCON(4) CKTXP: Clock/Transmit Polarity Select bit // Asynchronous mode: // 1 = Idle state for transmit (TX) is low // 0 = Idle state for transmit (TX) is high // BAUDCON(3) BRG16: 16-bit Baud Rate Generator bit // 1 = 16-bit Baud Rate Generator is used (SPBRGH:SPBRG) // 0 = 8-bit Baud Rate Generator is used (SPBRG) // BAUDCON(2) Unimplemented: Read as e0f // BAUDCON(1) WUE: Wake-up Enable bit // Asynchronous mode: // 1 = Receiver is waiting for a falling edge. No character will be received but RCIF will be set on // the falling edge. WUE will automatically clear on the rising edge. // 0 = Receiver is operating normally // BAUDCON(0) ABDEN: Auto-Baud Detect Enable bit // Asynchronous mode: // 1 = Auto-Baud Detect mode is enabled (clears when auto-baud is complete) // 0 = Auto-Baud Detect mode is disabled // ******************************************************* BAUDCON = 0b00001000; // ******************************************************* // 3.Define BRG(EUSART Baud Rate Generator Register) Register // ******************************************************* // BRG = 48000000(Hz)/4/9600(BPS)-1 ==> 0d1249 ==> 0x4E1 // BRG = 16000000(Hz)/4/9600(BPS)-1 ==> 0d0416 ==> 0x1A0 // BRG = 16000000(Hz)/4/19200(BPS)-1 ==> 0d0207 ==> 0x0CF // (1)Define SPBRGH(EUSART Baud Rate Generator Register, High Byte) Register SPBRGH = 0x01; // (2)Define SPBRG(EUSART Baud Rate Generator Register, Low Byte) Register SPBRG = 0xA0; } //****************************************************************************************** // Function Name : SendUART // Title : // Input : // Output : // Description : Write TXREG //****************************************************************************************** void SendUART(char put_data) { char chk_flg; // *************************** // 1.Check Send Flag // *************************** while(1){ chk_flg = TXSTA & 0x02; //0000,0010 TXSTA(TRMT) if(chk_flg != 0x00)break; } // *************************** // 2.Set data // *************************** TXREG = put_data; } //****************************************************************************************** // Function Name : ReciveUART // Title : // Input : // Output : // Description : Read RCREG //****************************************************************************************** void ReciveUART(char *get_data) { char chk_flg; // **************************** // 1.Check Recvive Flag // **************************** while(1){ chk_flg = PIR1 & 0x20; //0010,0000 PIR1(RCIF) if(chk_flg != 0x00)break; } // **************************** // 2.Check error // **************************** chk_flg = RCSTA & 0x06; //0000,0110 RCSTA(FERR,OERR) if(chk_flg != 0x00){ *get_data = 0x00; return; } // **************************** // 3.Set Recive Data // **************************** *get_data = RCREG; }