Difference between revisions of "GPS RECEIVER - MT3329"

From Teknologisk videncenter
Jump to: navigation, search
m
m (Data sheets)
 
(20 intermediate revisions by the same user not shown)
Line 18: Line 18:
  
 
==USART 1 code==
 
==USART 1 code==
To communicate with the GPS module the following code gives access to USART 1.
+
Communication with the GPS module has been achieved through expansion of the Keil RTX_Blinky example. This code is written using Keil uVision4.  
;NOTE:The example below is a codesnippet from the test code. The '''usart1_rx''' function should be called from an RTX thread called '''t_gps'''.
+
===Code for configuration and setup of USART1===
::*This is only test software. No buffer to hold unread data
 
 
<source lang=c>
 
<source lang=c>
USART1
+
int main (void)
CLOCK = PCLK1 AFTER APB1 PRESCALER
+
{
 +
        SystemInit();                            /* initialize clocks            */
  
BaudRate fck / ( 16 * USARTDIV )
+
        /* Setup GPIO for LEDs                                                    */
 +
        RCC->APB2ENR |= 1 <<  6;                /* Enable GPIOE clock            */
 +
        GPIOE->CRH    = 0x33333333;              /* Configure the GPIO for LEDs   */
  
Fx:
+
        GLCD_Init();                              /* Initialize the GLCD          */
  fck = 72 Mhz
+
        GLCD_Clear(White);                        /* Clear the GLCD                */
  Wanted BuadRate = 9.600
+
 
+
//Enable Port B clock and configure USART1 (with remapping of USART1 to Port B from Port A)
  USARTDIV = fck/ (16 * BaudRate ) =
+
RCC->APB2ENR |= 1 << 3;
    72000000/ (16 * 9600) = 468,75
+
RCC->CFGR |= 4 << 10;
 
+
RCC->APB2ENR |= 1 << 0;
Mantissa = 438 - as hex = 0x1D4
+
AFIO->MAPR |= 1 << 2;
Fraction = 16*0.75 = 6 - as hex 0xC
+
*/
+
//Enable GPIOB7 as rx, GPIOB6 as tx (Pin7: 0100, Pin6: 1011)
void usart1_enable( void) {
+
        GPIOB->CRL &= 0x00FFFFFF;
//Step  1: RCC_APB2ENR - Enable Clock for Port B
+
        GPIOB->CRL |= 0x4B000000;
rcc_apb2enr(1 << 3,ENABLE);
+
 
+
//Enable USART in RCC_APB2ENR
//Step 2: RCC_CFGR bits PPRE1[2:0] = 100 -APB1 Prescaler divide by 2 = 36 MHz
+
RCC->APB2ENR |= 1 << 14;
rcc_cfgr( 0x00000300, 0 ); //Set PPRE1[1:0] = 0
+
rcc_cfgr( 0x00000400, 1 ); //Set PPRE1[2] = 1
+
/*
 
+
Set baud rate (USART_BRR): BaudRate =  fck / ( 16 * USARTDIV )
//Step  3: RCC_APB2ENR - Enable AFIO Clock - Alternate Clock I/O Enable
+
    For example:
rcc_apb2enr(1 << 0,ENABLE);
+
        fck = 72 MHz
 
+
    required Baud Rate = 9600
//Step  4: AFIO_MAPR - Remap USART1  to Port B
+
rcc_afio_mapr(1 << 2, ENABLE);
+
    USARTDIV = fck/(16 * BaudRate ) = 72000000/(16 * 9600) = 468.75
 
+
//Step 5.1 and 5.2 - Enable pin 7 as RX and pin 6 as TX
+
    Mantissa = 438 - as hex: 0x1D4
GPIOB->CRL &= 0x00FFFFFF;
+
    Fraction = 16*0.75 = 12 - as hex: 0xC
GPIOB->CRL |= 0x4B000000;   //Pin 7: 0100 Pin 6: 1011
+
 
+
    See Reference Manual for further details
//Step  6: RCC Enable USART in RCC_APB2ENR
+
*/
rcc_apb2enr( 1 << 14, ENABLE); //set bit 14 in RCC_APB2ENR (Enable USART1)
+
USART1->BRR = 0x01d4c;
 
+
//Step  7.1 and 7.2: USART_BRR bits DIV_Mantissa[11:0] = 0x1d4 and fraction = c
+
//USART enable
USART1->BRR = 0x01d4c;
+
USART1->CR1 |= 1 << 13;
 
+
//Step  8: USART_CR1 bit UE - Uart Enable = 1
+
//USART Tx enable
USART1->CR1 |= 1 << 13;
+
USART1->CR1 |= 1 << 3;
 
+
//Step 13: USART_CR1 bit TE - Tranmitter enable = 1
+
//USART Rx enable
USART1->CR1 |= 1 << 3;
+
USART1->CR1 |= 1 << 2;
 
+
//Step 14: USART_CR1 bit RE - Receiver enable = 1
+
//USART Rx Interrupt enable
USART1->CR1 |= 1 << 2;
+
USART1->CR1 |= 1 << 5;
 
+
//Step 15: USART_CR1 bit RXNEIE - Receiver interrupt enable = 1
+
//Send initialisation messages to the GPS, 1: Baud rate, 2: Reset GPS to output default NMEA messages
USART1->CR1 |= 1 << 5;
+
putstr("$PMTK251,9600*17\r\n");
 +
putstr("$PMTK314,-1*04\r\n");
 +
 +
NVIC_EnableIRQ(USART1_IRQn);
  
 +
        os_sys_init (init);        /* Initialize RTX and start init */
 
}
 
}
  
void usart1_tx( char character ) {
+
void usart1_tx(char character)  
 +
{
 
while ((USART1->SR & ( 1 << 6)) == 0) {}; // Wait HSERDY = 1
 
while ((USART1->SR & ( 1 << 6)) == 0) {}; // Wait HSERDY = 1
 
USART1->DR = (uint16_t) character;
 
USART1->DR = (uint16_t) character;
 
}
 
}
void putstr(char *string) {
+
 
 +
void putstr(char *string)  
 +
{
 
int i;
 
int i;
for ( i=0; string[i] != 0; i++ ) {
+
for ( i=0; string[i] != 0; i++ )
 +
        {
 
usart1_tx(string[i]);
 
usart1_tx(string[i]);
 
}
 
}
 
}
 
}
  
//Receive
+
//USART1 Interrupt Handler
char usart1_rx() {
 
os_evt_wait_and (0x0001, 0xffff);
 
return(USART1->DR);
 
}
 
  
void USART1_IRQHandler( void ) __irq {
+
void USART1_IRQHandler(void) __irq
 +
{
 +
NVIC_DisableIRQ(USART1_IRQn);
 
 
isr_evt_set(0x0001, t_gps);  
+
//Send event flag to t_gps task
while ((USART1->SR & ( 1 << 5)) == 0) {}; // Wait RXNE = 1
+
isr_evt_set(0x1111, t_gps);
 +
 +
//Reset USART status register to allow the next value from the serial link to be set
 +
USART1->SR &= ~(1 << 5);
 +
 +
NVIC_EnableIRQ(USART1_IRQn);
 +
}
 +
</source>
 +
===Code for handling incoming data===
 +
<source lang=c>
 +
// Global array received[] used to allow output to be seen in debugger.
 +
// Use of the global array would also be relevant to allow data to be passed between tasks.
 +
// This approach would require use of mutexes when writing to and reading from the array, to ensure that only complete messages are saved
 +
// This is a very minimal implementation to allow viewing of received messages in the debugger.
 +
// More work is required to make a robust character buffer...
  
 +
__task void gps(void)
 +
{
 +
int i = 0;
 +
        for(;;)
 +
{
 +
    os_evt_wait_and(0x1111, 0xffff);
 +
    received[i] = USART1->DR;
 +
 +
            // Check for standard NMEA message ending (CR/LF)           
 +
            if(received[i]==0x0A  && received[i-1]==0x0D)
 +
    {
 +
                i=0;
 +
    }
 +
    else
 +
    {
 +
        i++;
 +
        i=i%MAX_MESSAGE_SIZE;
 +
    }
 +
}
 
}
 
}
 
</source>
 
</source>
 +
 +
===General configuration and setup===
 +
<source lang=c>
 +
OS_TID t_phaseA;                        /* assigned task id of task: phase_a */
 +
OS_TID t_phaseB;                        /* assigned task id of task: phase_b */
 +
OS_TID t_phaseC;                        /* assigned task id of task: phase_c */
 +
OS_TID t_phaseD;                        /* assigned task id of task: phase_d */
 +
OS_TID t_clock;                        /* assigned task id of task: clock  */
 +
OS_TID t_lcd;                          /* assigned task id of task: lcd    */
 +
OS_TID t_gps;         /* assigned task id of task: gps    */
 +
 +
OS_MUT mut_GLCD;                        /* Mutex to control GLCD access    */
 +
 +
#define LED_A  0
 +
#define LED_B  1
 +
#define LED_C  2
 +
#define LED_D  3
 +
#define LED_CLK 7
 +
 +
#define LED_NUM    8                  /* Number of user LEDs                */
 +
 +
#define MAX_MESSAGE_SIZE 100
 +
const long led_mask[] = { 1<<15, 1<<14, 1<<13, 1<<12, 1<<11, 1<<10, 1<<9, 1<<8 };
 +
unsigned char received[MAX_MESSAGE_SIZE];
 +
</source>
 +
===Configuration settings for RTX===
 +
[[File:Keil-RTX-configuration-for-GPS-reader.png]]
  
 
=Data sheets=
 
=Data sheets=
 +
*[http://mars.tekkom.dk/mediawiki/images/a/a7/PmodGPS_rm.pdf Digilent PB200 datasheet]
 
*[http://mars.tekkom.dk/data/embedded/GPS/DIYDrones%20Custom%20Binary%20Protocol%20-%20Google%20Drev.pdf Binary Protocol]
 
*[http://mars.tekkom.dk/data/embedded/GPS/DIYDrones%20Custom%20Binary%20Protocol%20-%20Google%20Drev.pdf Binary Protocol]
 
*[http://mars.tekkom.dk/data/embedded/GPS/MTK%20Commands%20-%20Google%20Drev.pdf MTK Commands]
 
*[http://mars.tekkom.dk/data/embedded/GPS/MTK%20Commands%20-%20Google%20Drev.pdf MTK Commands]

Latest revision as of 13:27, 22 October 2014

Module on MCBSTM32C Keil board

Picture 1: GPS Module attached to Keil board. (Click to enlarge)
Picture 2: Wires attached between Keil board and 6 pin connecter. Display removed. (Click to enlarge)
Picture 3: GPS Module attached to 6 pin connector on Keil board.(Click to enlarge)

Using the STM32F107VC remapped USART1 to PB6 (USART1_TX)and PB7 (USART1_RX). The GPS module uses VCC and GND and not RS232 levels on TX/RX. Five boards are modified for the five GPS modules bought.

  • The [1] show that PB6 is used for CAN2 bus TX. CAN2 bus can't be used at the same time as the GPS module.
  • The [2] show that PB7 is used for the USER button. To use PB7 as RX from the GPS module it is necessary to remove C20. The USER switch can't be used at the same time as the GPS module.

Connections

Solder a 6 pin 0,1 inch 90 degrees angle. See picture 2 and connect

  • Pin 1 to 3,3V (Red wire)
  • Pin 2 to GND (Black wire)
  • Pin 3 - Not used in this project ( 1 second pulse signal from GPS module )
  • Pin 4 to PB7 (Orange wire) - GPS module TX
  • Pin 5 to PB6 (Yellow wire) - GPS module RX
  • Pin 6 - NOt used in this project ( FIX signal )

Battery connector on keil board

The minus pole on the battery has no electrical connection to the main board. To make a connection a desisolated wire was placed between the minuspole on the battery and the goldplated area on the PCB under the battery. See picture 2.

USART 1 code

Communication with the GPS module has been achieved through expansion of the Keil RTX_Blinky example. This code is written using Keil uVision4.

Code for configuration and setup of USART1

int main (void) 
{
        SystemInit();                             /* initialize clocks             */

        /* Setup GPIO for LEDs                                                     */
        RCC->APB2ENR |=  1 <<  6;                 /* Enable GPIOE clock            */
        GPIOE->CRH    = 0x33333333;               /* Configure the GPIO for LEDs   */

        GLCD_Init();                              /* Initialize the GLCD           */
        GLCD_Clear(White);                        /* Clear the GLCD                */
	
	//Enable Port B clock and configure USART1 (with remapping of USART1 to Port B from Port A)
	RCC->APB2ENR |= 1 << 3;
	RCC->CFGR  |= 4 << 10;
	RCC->APB2ENR |= 1 << 0;
	AFIO->MAPR |= 1 << 2;
	
	//Enable GPIOB7 as rx, GPIOB6 as tx (Pin7: 0100, Pin6: 1011)
        GPIOB->CRL &= 0x00FFFFFF;
        GPIOB->CRL |= 0x4B000000;	
	
	//Enable USART in RCC_APB2ENR
	RCC->APB2ENR |= 1 << 14;
	
	/*
	Set baud rate (USART_BRR): BaudRate =   fck / ( 16 * USARTDIV )
	    For example:
	        fck = 72 MHz
		    required Baud Rate = 9600
		 
		    USARTDIV = fck/(16 * BaudRate ) = 72000000/(16 * 9600) = 468.75
		 
		    Mantissa = 438 - as hex: 0x1D4
		    Fraction = 16*0.75 = 12 - as hex: 0xC
			
		    See Reference Manual for further details
	*/ 
	USART1->BRR = 0x01d4c;
	
	//USART enable
	USART1->CR1 |= 1 << 13;
	
	//USART Tx enable
	USART1->CR1 |= 1 << 3;
	
	//USART Rx enable
	USART1->CR1 |= 1 << 2;
	
	//USART Rx Interrupt enable
	USART1->CR1 |= 1 << 5;
	
	//Send initialisation messages to the GPS, 1: Baud rate, 2: Reset GPS to output default NMEA messages
	putstr("$PMTK251,9600*17\r\n");
	putstr("$PMTK314,-1*04\r\n");
	
	NVIC_EnableIRQ(USART1_IRQn);

        os_sys_init (init);        /* Initialize RTX and start init */
}

void usart1_tx(char character) 
{
	while ((USART1->SR & ( 1 << 6)) == 0) {}; // Wait HSERDY = 1
	USART1->DR = (uint16_t) character;
}

void putstr(char *string) 
{
	int i;
	for ( i=0; string[i] != 0; i++ )
        {
		usart1_tx(string[i]);
	}
}

//USART1 Interrupt Handler

void USART1_IRQHandler(void) __irq
{
	NVIC_DisableIRQ(USART1_IRQn);
	
	//Send event flag to t_gps task
	isr_evt_set(0x1111, t_gps);	
	
	//Reset USART status register to allow the next value from the serial link to be set
	USART1->SR &= ~(1 << 5);
	
	NVIC_EnableIRQ(USART1_IRQn);
}

Code for handling incoming data

// Global array received[] used to allow output to be seen in debugger.
// Use of the global array would also be relevant to allow data to be passed between tasks.
// This approach would require use of mutexes when writing to and reading from the array, to ensure that only complete messages are saved 
// This is a very minimal implementation to allow viewing of received messages in the debugger.
// More work is required to make a robust character buffer...

__task void gps(void)
{
	int i = 0;
        for(;;)
	{
	     os_evt_wait_and(0x1111, 0xffff);
	     received[i] = USART1->DR;
		
             // Check for standard NMEA message ending (CR/LF)             
             if(received[i]==0x0A  && received[i-1]==0x0D)
	     {
                i=0;
	     }
	     else
	     {
	         i++;
	         i=i%MAX_MESSAGE_SIZE;
	     }
	}
}

General configuration and setup

OS_TID t_phaseA;                        /* assigned task id of task: phase_a */
OS_TID t_phaseB;                        /* assigned task id of task: phase_b */
OS_TID t_phaseC;                        /* assigned task id of task: phase_c */
OS_TID t_phaseD;                        /* assigned task id of task: phase_d */
OS_TID t_clock;                         /* assigned task id of task: clock   */
OS_TID t_lcd;                           /* assigned task id of task: lcd     */
OS_TID t_gps;			        /* assigned task id of task: gps     */

OS_MUT mut_GLCD;                        /* Mutex to control GLCD access     */

#define LED_A   0
#define LED_B   1
#define LED_C   2
#define LED_D   3
#define LED_CLK 7

#define LED_NUM     8                   /* Number of user LEDs                */

#define MAX_MESSAGE_SIZE 100
const long led_mask[] = { 1<<15, 1<<14, 1<<13, 1<<12, 1<<11, 1<<10, 1<<9, 1<<8 };
unsigned char received[MAX_MESSAGE_SIZE];

Configuration settings for RTX

Keil-RTX-configuration-for-GPS-reader.png

Data sheets

ARM board projects


Links