打印

PSoC1 GPIO揭秘

[复制链接]
3971|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Go_PSoC|  楼主 | 2011-5-12 20:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
Go_PSoC|  楼主 | 2011-5-12 20:59 | 只看该作者
[url=]PSoC 1 GPIO Demystified - Part 1[/url]
By M Ganesh Raaja
GPIOs play an important role in creating a bridge between the internals of a microcontroller to the external world.  Let us take a look at the important features of PSoC 1 GPIO and application scenarios.  Because of the large amount of information to be covered, I have split this into a two part series.
Part-1 is about various features of the GPIO like the Drive modes, GPIO registers, Interrupts and the PSoC Designer interface to configure the GPIO.  This is mostly boring stuff from the Technical Reference Manual. If you would like to get to the interesting stuff, skip to Part-2 which covers application scenarios like writing to a GPIO, reading from a GPIO, Read Modify Write Instructions and writing a GPIO ISR.
DRIVE MODES
PSoC1 GPIO pins can be configured into one of 8 drive modes.


#
Drive Mode
HIGH
LOW
Comments
1
Pull down
Strong
Resistive
Input / Output
2
Strong
Strong
Strong
Output
3
High Impedance
HighZ
HighZ
Input (Schmitt Trigger enabled)
4
Pull Up
Resistive
Strong
Input / Output
5
Open Drain High
Strong
HighZ
Input / Output
6
Slow Strong
Strong Slow
Strong Slow
Output (Slope controlled)
7
High Impedance Analog
HighZ
HighZ
Analog Input / Output
8
Open Drain Low
HighZ
Strong Slow
Input / Output, I2C

Strong and Slow Strong are used as outputs.  The Slow strong mode introduces a slew rate control on the pin that increases the slope on the rising and falling edges of the pins thus reducing EMI and RFI radiations.
HighZ mode is used as input for both analog and digital signals and also for analog output.  HighZ Analog mode is used for Analog input and output.  Remember, in the HighZ Analog mode, the Schmitt trigger circuit on the digital input path is disabled and hence the pin cannot be used to read digital signals nor will it generate interrupts.
Pull Up, Pull Down, Open Drain High, and Open Drain Low can be used as Input as well as Output.  An exception is when a pin is connected to the Global Input bus to route the signal to a digital block.  When a pin is connected to the Global Input bus, it cannot be configured in Pull up or Pull down modes.
REGISTERS
The GPIO pins are controlled by various registers.
Data Register: The state of a GPIO can be controlled / read by writing / reading the PRTxDR register.  For example to make P1[5] HIGH, Bit5 of PRT1DR should be set.  More about writing and reading GPIO pins in Part-2.
Drive Mode Registers:  There are three drive mode registers for each port that control the drive mode of the pins in a particular port.  These are the PRTxDM0, PRTxDM1 and PRTxDM2 registers. The combination of the bits of these three registers decide the drive mode of a particular pin.  For example, the drive mode of P2[3] will be decided the combination of Bit3 of PRT2DM0, PRT2DM1 and PRT2DM2 registers.  Details can be found in the Technical Reference Manual.
Global Select register: The PRTxGS register decides if a GPIO pin is under the control of the CPU or is connected to the Global In or Global Out bus.  When the bit in PRTxGS register is cleared, the pin can be controlled by the CPU by writing to the PRTxDR register.  When the bit in PRTxGS register is set, the pin is connected to the Global bus and connects to the internal hardware blocks.
Interrupt Control Registers: PRTxIE, PRTxIC0 and PRTxIC1 are registers that control the interrupt mode of a GPIO pin.

INTERRUPTS
Each GPIO pin may be configured to generate an interrupt on Rising Edge, Falling Edge or a Change from Read event.  The interrupt behavior of GPIO pins are controlled by the following registers.
PRTxIE Register: This register enables or disables the interrupt for a particular GPIO pin.  For example, if the interrupt has to be enabled on P1[5], Bit5 of PRT1IE register has to be set.  When the interrupt type is selected in the GPIO configuration pane in the PSoC Designer device editor, the designer automatically sets the PRTxIE register in the boot up code.
PRTxIC0 and PRTxIC1 Registers: These two registers are used in combination to choose between four options of interrupt type for each pin – Disabled, Rising Edge, Falling Edge and Change from Read.  Following are the bit combinations of PRTxIC0 and PRTxIC1 registers.  For example to configure P2[1] as a Rising Edge interrupt, Bit1 of PRT2IC0 should be cleared and Bit1 of PRT2IC1 should be set.  When the interrupt type is selected in the GPIO configuration pane in the PSoC Designer device editor, the designer automatically sets the PRTxIC0 and PRTxIC1 registers accordingly in the boot up code.
When the pin is configured for a Change From Read interrupt, an interrupt is generated whenever the state of the pin changes from the state that was read from the pin.  So, to generate an interrupt from both rising and falling edges, whenever an interrupt is generated from the pin, a read operation should be performed on the PRTxDR register.  Even if there is no requirement for such a read, a dummy read operation has to be performed for the interrupt to work.
INT_MSK0 Register:  Bit5 in the INT_MSK0 bit is the Mask bit for GPIO interrupt.  Only when this bit is set, the interrupts raised by GPIO pins will be processed by the CPU.  The device editor does not take care of setting this bit.  This bit has to be set in the firmware.
Notes:
  • Remember to enable the Global interrupts for the GPIO interrupt (or any other interrupts) to work.
  • If the drive mode is set to “HighZ Analog”, interrupt will not work.
PSOC DESIGNER – CONFIGURING A GPIO
All the GPIO pins can be configured using the GPIO configuration window in the PSoC Designer device editor.

Name: Giving meaningful names to the GPIO pins will make the project more readable.  For example, LED, SPI_MOSI, SPI_MISO, UART_TX etc.  Giving names to the GPIO also will be useful in controlling the pins using the register definitions in the psocgpioint.h file.  More about this later.
Select: This parameter selects the mode of the pin like Analog Input, Global Input, Global Output etc.  On specific pins, special functions like XTAL_IN, XTAL_OUT, I2C_SCL, I2C_SDA etc also will be available.  When the type of pin is selected, the drive mode will be automatically be set.
Drive:  This parameter selects one of 8 drive modes for the pin.  Though the drive mode will be automatically set according to the pin type selected in the previous parameter, it can be overridden.
Interrupt: This parameters sets the interrupt type of the pin

使用特权

评论回复
板凳
Go_PSoC|  楼主 | 2011-5-12 20:59 | 只看该作者
[url=]PSoC 1 GPIO Demystified - Part 2[/url]
By M Ganesh Raaja
In Part-1 we looked at the features of the PSoC1 GPIO.  In this part, let us look at application scenarios.
WRITING TO A GPIO PIN
To control a GPIO using the CPU, first the GPIO pin should be set to StdCPU mode in the GPIO configuration window in device editor.  This will clear the corresponding bit in the PRTxGS register disconnecting the pin from the Global bus.  The drive mode should be set to any mode other than HighZ or HighZ Analog.  Now the pin may be controlled by writing to the PRTxDR register.  Following are some examples in assembly and C.
Assembly Examples:
or reg[PRT1DR], 0x02     ; Set P1[1]
and reg[PRT1DR], ~0x80   ; Clear P1[7]
xor reg[PRT0DR], 0x04    ; Toggle P0[2]


C Examples:
PRT1DR |= 0x02;     // Set P1[1]
PRT1DR &= ~0x80;    // Clear P1[7]
PRT0DR ^= 0x04;     // Toggle P0[2]


Notes:
  • M8C.inc file has the register definitions for assembly and m8c.h file has the register definitions for C.
  • While writing in assembly make sure that the Register bank is set to 0 before writing to the PRTxDR register.  Register bank may be set to 0 by using the M8C_SetBank0 macro
  • While using C, the compiler takes care of register bank switching.
However, this method has a disadvantage that it is not portable.  For example, let us say we have placed an LED on P0[5] and have used PRT0DR to control the LED.  Later in the design cycle of the project, the LED is to be moved to P1[2].  Now we will have to search all the locations in the project where PRT0DR is accessed and change this to PRT1DR.  Using Pin names will solve this problem.  Below is the procedure.
1.    Give a meaningful name to the pin to be controlled.  For example “LED”
2.    PSoC designer generates include files called psocgpioint.inc and psocgpioint.h, which has defines for the registers and masks for the pins.
3.    Include psocgpioint.inc or psocgpioint.h file in the C or assembly source file.  Now the pins can be controlled by using code like:
LED_Data_ADDR |= LED_MASK;  // C Code
or reg[LED_Data_ADDR], LED_MASK   ; Assembly code

Now, if the LED were to be moved to any other port, the register definition in the psocgpiont.inc and psocgpioint.h files will be automatically updated by the PSoC designer and there will be no need to change the application code.
READING A GPIO PIN

The state of a GPIO can be read by reading the PRTxDR register.  One important thing to bear in mind is that the PRTxDR register reflects the state of the GPIO pin, not the value that was written to the register.  For example, if you had written a 1 to a GPIO pin configured as a pull up and when reading the PRTxDR register, if the pin were shorted to GND externally, the value read from the PRTxDR will be 0, not 1.  This behavior gives rise to some interesting but unwanted situations which are explained in the next section on Read Modify Write operations.
Following are C and Assembly code examples to read from a GPIO pin.  Either the PRTxDR can be directly used or register and mask names from psocgpioint include files can be used.  In the below examples, an input pin named SWITCH is read.

Assembly Example:
mov A, reg[SWITCH_Data_ADDR]
and A, SWITCH_MASK
jnz PinHigh
; Pin state is Low
PinHigh:
   ; Pin state is high.

C Example:
if (SWITCH_Data_ADDR & SWITCH_MASK)
{
    // Pin is set.  Add code to process
}

Notes:
  • When a GPIO pin has to be configured as a digital input, set the drive mode to HighZ, not HighZ Analog.  As the Schmitt trigger section in the GPIO cell is disabled in the HighZ Analog mode, the state of the PRTxDR register bit corresponding to the pin will always be zero.
  • When a pin is configured for Pull Up mode, for example to read an external switch connected between the pin and GND, a 1 has to be written to the PRTxDR register bit to enable the pull up resistor.  Similarly, when a GPIO is configured in Pull Down mode, a 0 has to be written to the PRTxDR register bit.
READ MODIFY WRITE INSTRUCTIONS AND SHADOW REGISTERS

When you have input pins configured as Pull Up or Pull Down, and if there are other pins on the same port which are configured as output pins, an instruction that is used to update an output pin may accidentally set or clear the input pin thus latching the input.  For example let us consider the following scenario.
P1[0] - PullUP, Connected to a switch. 1 has been written to the bit in PRT1DR to enable the pullup
P1[1] - Strong, drives an LED.
Now, the following instruction is used to switch off the LED
and reg[PRT1DR],~0x02
The above instruction is a Read/Modify/Write instruction, ie, it first reads the pin states (not the value written to PRT1DR register before), does an “AND” operation with the mask and then writes back the result to PRT1DR register.  If the switch were pressed when this instruction is executed, the pin state of P1[0] would be 0, so the result of the operation would be
Pin State: x x x x x x x 0
AND operation: (x x x x x x x 0) & (11111101) = x x x x x x 0 0
Write back: x x x x x x 0 0
Bit-0 which drives the switch has been cleared in PRT1DR now and will never become high.  This will result in the input pin stuck to 0, irrespective of the state of the switch.
A workaround for this condition is using Port shadow registers. Declare a variable in RAM and initialize this variable in the beginning of code to the initial Port value. After this, do any Read/Modify/Write operation on this shadow register and then write the value of shadow register to the PRTxDR register.
// Declare a shadow register
BYTE Port1Shadow;
// Initialize in the beginning of code
// Bit0 is set to enable the Pullup for the key
Port1Shadow = 0x01;
PRT1DR = Port1Shadow;
// Now to clear the LED
Port1Shadow &= ~0x02;
PRT1DR = Port1Shadow;

WRITING A GPIO ISR
Now, let us configure a GPIO pin for interrupt and write an ISR that increments a variable “IntCount”.  In the Device Editor GPIO configuration, set the interrupt to the desired type.  The PSoC Designer will take care of the PRTxIE and PRTxICx registers in the boot.asm code
In main, enable the Global interrupt by using the M8C_EnableGInt macro
In main,enable the GPIO interrupt by using the below code.
M8C_EnableIntMask(INT_MSK0, INT_MSK0_GPIO);   // C code to enable GPIO interrupt
M8C_EnableIntMasm INT_MSK0, INT_MSK0_GPIO   ; Assembly code

Whenever a pin is enabled for interrupt in the PSoC Designer Device editor, the IDE generates a file called psocgpioint.asm.  This file has the place holder to write an ISR for the GPIO interrupt.  The following code should be added within the user code marker in the ISR function.
PSoC_GPIO_ISR:
   
   ;@PSoC_UserCode_BODY@ (Do not change this line.)
   ;---------------------------------------------------
   ; Insert your custom code below this banner
   ;---------------------------------------------------
   inc [IntCount]
   ;---------------------------------------------------
   ; Insert your custom code above this banner
   ;---------------------------------------------------
   ;@PSoC_UserCode_END@ (Do not change this line.)

   reti

If you would like to write the ISR in C, then do the following.
Declare the ISR function using #pragma interrupt_handler
#pragma interrupt_handler MyGpioISR
Write the interrupt handler function.
void MyGpioISR(void)
{
   IntCount++;
}

In the psocgpioint.asm file, place an ljmp instruction to branch to the C ISR
PSoC_GPIO_ISR:
   
   ;@PSoC_UserCode_BODY@ (Do not change this line.)
   ;---------------------------------------------------
   ; Insert your custom code below this banner
   ;---------------------------------------------------
   ljmp _MyGpioISR
   ;---------------------------------------------------
   ; Insert your custom code above this banner
   ;---------------------------------------------------
   ;@PSoC_UserCode_END@ (Do not change this line.)

   reti

使用特权

评论回复
地板
冰清玉洁| | 2011-5-12 21:31 | 只看该作者
:Q全英文,看着真累

使用特权

评论回复
5
qwasd| | 2011-5-12 22:28 | 只看该作者
I like English materials!

使用特权

评论回复
6
傳說勝劍| | 2011-5-13 09:11 | 只看该作者
顶下……

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

898

主题

5336

帖子

15

粉丝