PIC Programming Based on PICC Compilation Environment

Publisher:云淡雅致Latest update time:2010-10-18 Source: 电子发烧友Keywords:PICC  PIC  compiler  program Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

This article mainly introduces the basic characteristics of PIC's C language based on HiTech PICC .

1 Features of HiTech PICC language

PICC basically complies with the ANSI standard, but does not support recursive function calls. The main reason is the special stack structure of the PIC microcontroller. The stack in the PIC microcontroller is implemented in hardware, and its depth is fixed with the chip, so it is impossible to implement recursive algorithms that require a large number of stack operations; in addition, the efficiency of implementing software stacks in PIC microcontrollers is not very high. For this reason, the PICC compiler uses a "static overlay" technology to allocate a fixed address space to local variables in C language functions. The machine code generated after this treatment is very efficient. When the code size exceeds 4KB, the difference between the length of the code compiled by C language and the code implemented entirely in assembly code is not very large (<10%). Of course, the premise is that you need to pay attention to the efficiency of the statements written during the entire C code writing process.

2 Variables in PICC

The variable types in PICC are the same as those in standard C language, so they will not be repeated here. In order to make the compiler generate the most efficient machine code, PICC lets the programmer manage the banks of data registers in the microcontroller. Therefore, when defining user variables, you must decide which bank to put these variables in. If not specified, the defined variables will be located in bank0. The corresponding bank number must be added in front of the variables defined in other banks, for example:

bank1 unsigned char temp; // variable is located in bank1

The data register bank size of the mid-range PIC microcontroller is 128 bytes. Except for the special function register area of ​​the first few bytes, the total number of variable bytes defined in a bank in C language cannot exceed the number of available RAM bytes. If the bank capacity is exceeded, an error will be reported at the last connection, and the general information is as follows:

Error[000]:Can't find 0x12C words for psect rbss_1 in segmentBANK1

The linker prompts that there are a total of 0x12c (300) bytes to be placed in bank 1, but the capacity of bank 1 is insufficient. Although the bank location of the variable must be determined by the programmer, there is no need to specifically write instructions to set the bank before performing variable access operations when writing the source program. The C compiler will automatically generate assembly instructions for the corresponding bank settings based on the object being operated. In order to avoid frequent bank switching and improve code efficiency, try to locate variables that implement the same task in the same bank; when reading and writing variables in different banks, try to merge variables in the same bank together for continuous operations.

Bit variables can only be global or static. PICC will merge 8 bit variables located in the same bank into one byte and store it at a fixed address. PICC implements bit addressing for the entire data storage space. The address of the 0th bit of the 0x000 unit is 0x0000, and so on. Each byte has 8 bit addresses. If a bit variable flag1 is addressed as 0x123, the actual storage space is located at:

Byte address = 0x123/8 = 0x24

Bit offset = 0x123%8 = 3

That is, the flag1 bit variable is located at the third bit of the byte at address 0x24. When debugging the program, if you want to observe the change of flag1, you must observe the byte at address 0x24 instead of 0x123. When PICC compiles the original code, whenever possible, the operation of ordinary variables will be implemented with the simplest bit operation instructions. Assuming that a byte variable tmp is finally located at address 0x20, then

tmp | =0x80=>bsf 0x20.7

In addition, the function can return a bit variable, and the returned bit variable will be stored in the carry bit of the microcontroller and returned.

3 Pointers in PICC

3.1 Pointers to RAM

When PICC compiles the C source program, the pointer operation pointing to RAM is finally implemented with FSR for indirect addressing. The range that FSR can directly and continuously address is 256B, so a pointer can cover the storage area of ​​2 banks at the same time (bank0/1 or bank2/3, one bank area is 128B). To cover the maximum 512B of internal data storage space, the addressing area applicable to the pointer must be clearly specified when defining the pointer. For example:

unsigned char *pointer0; //Define the pointer that overwrites bank0/1

bank2 char *pointer1; //Define the pointer that covers bank2/3

Since the defined pointer has a clear bank applicable area, type matching must be achieved when assigning values ​​to pointer variables, otherwise an error will occur, for example:

unsigned char *pointer0; //define the pointer to bank0/1

bank2 unsigned char buff; //define a buffer in bank2/3

Program statements:

pointer() = buff; //Error! Trying to assign the address of a variable in bank2 to a pointer pointing to bank0/1

If such incorrect pointer operation occurs, the PICC will notify you of the following information at the last link:

Fixup overflow in expression (…)

3.2 Pointers to ROM constants

If a set of variables are constants that have been defined in the ROM area, then the pointer to them can be defined like this:

const unsigned char company[]="software"

3.3 Pointers to functions

Because the efficiency of implementing function pointer calls on the specific architecture of PIC microcontrollers is not high, it is recommended that you try not to use function pointers unless required by special algorithms.

4 Subroutines and functions in PICC

The program space of the mid-range PIC microcontroller has the concept of paging, but you don't need to worry too much about the paging of the code when programming in C language, because the page setting when calling all functions or subroutines (if the code exceeds one page) is implemented by the instructions automatically generated by the compiler.

4.1 Function code length limit

PICC determines that the machine code generated by a function in a C source program after compilation must be placed in the same program page. The length of a program page of a mid-range PIC microcontroller is 2KB, and the code generated by any function written in C language cannot exceed 2KB. If you really need to write a long program continuously to achieve a specific function, then you must split these continuous codes into several functions to ensure that the code compiled by each function does not exceed one page space.

4.2 Call hierarchy control

PIC microcontrollers use hardware stacks, so the function call level will be subject to certain restrictions during programming. Generally, the hardware stack depth of the mid-range microcontrollers in the PIC series is 8 levels. The programmer must control the nesting depth of the subroutine call to meet this restriction. After the final compilation and linking of PICC is successful, a link positioning mapping file (*.map) can be generated. In this file, there is a detailed function call nesting indicator graph "call graph". Some function calls are library functions automatically added during compilation. These function calls cannot be directly seen from the C source program, but they are clear at a glance on the nesting indicator graph.

5 Mixed programming of C language and assembly language

Some special instructions of the microcontroller have no direct corresponding description in the standard C language syntax, such as the clear watchdog instruction "clrwdt" and the sleep instruction "sleep" of the PIC microcontroller; the microcontroller system emphasizes the real-time control. In order to achieve this requirement, sometimes it is necessary to use assembly instructions to implement part of the code to improve the efficiency of program operation. There are two ways to embed assembly instructions in C programs.

① If only a few assembly instructions need to be embedded, PICC provides a function-like statement:

asm("clrwdt");

This is the most direct and easiest way to embed assembly instructions directly in a C source program.

② If you need to write a continuous assembly instruction, PICC supports another syntax description: use "#asm" to start the assembly instruction segment and "#endasm" to end it. For example:

PICC assembly instructions www.elecfans.com

5.1 Assembly instructions addressing global variables defined in C language

All symbols defined in C language will be automatically preceded by an underscore "_" after compilation. Therefore, if you want to address various variables defined in C language in assembly instructions, you must add the "_" symbol in front of the variable. For example, count in the above example is an unsigned global variable defined in C language. In assembly language, you only need to add the "_" symbol in front of it to access it. In addition, for multi-byte global variables defined in C language, such as the following definition in C language:

int advalue;

In assembly language, access is done by byte, for example:

asm("movf_advalue+0.0"); //Send the number in the low byte of advalue to w

asm("rrf_advalue+1") //Shift the number in the high byte of advalue one bit to the left

5.2 Assembly instructions addressing local variables of C functions

As mentioned above, PICC uses a "static overwrite" technology for automatic local variables (including entry parameters when calling functions), and determines a fixed address (located in bank0) for each variable. When the embedded assembly instructions address it, they only need to use the direct addressing method of the data register. Therefore, the key is to know the addressing symbols of these local variables. It is recommended that readers first write a short C code with the simplest local variable operation instructions, and compile this source code into the corresponding PICC assembly instructions; check how the assembly instructions generated by the C compiler address these local variables, and use the same addressing method for the inline assembly instructions written by yourself.

Compared with assembly language, the advantages of programming in C language are unquestionable: development efficiency is greatly improved, humanized statement instructions and modular programs are easy to manage and maintain, and programs are easy to port between different platforms. Therefore, since you use C language for programming, you should try to avoid embedding assembly instructions or writing assembly instruction module files. For example:

It is very inconvenient to implement the variable right-shift operation in C language. The PIC microcontroller has the corresponding shift operation assembly instruction, so it is most efficient to implement it in the form of embedded assembly. In fact, the decrement of the variable count1 can also be directly implemented with assembly instructions, which can save code, but it is more intuitive and easier to maintain to describe it in standard C language.

6. Notes

① Since all local variables will occupy the storage space of bank0, the number of bytes of variables that users can locate in bank0 will be subject to certain restrictions. Please pay attention to this in actual use.

② When a non-bit variable is forcibly converted into a bit variable in the program, please note that the compiler only judges the lowest bit of the ordinary variable: if the lowest bit is 0, it is converted into bit variable 0; if the lowest bit is 1, it is converted into bit variable 1.

③ Since the internal resources of the PIC series microcontrollers are very limited, unsigned character type variables should be used as much as possible under permitted conditions to save space.

④ PICC does not reserve address space for absolutely positioned variables, for example:

unsigned char advalue @ 0x20; //advalue is located at address 0x20, which is equivalent to a pseudo-instruction in assembly language

advalue EQU 20H

So please use it with caution.

⑤ Try to use global variables for parameter passing. The biggest advantage of using global variables is that addressing is intuitive. You only need to add an underscore character before the variable name defined in C language to address it in the assembly statement. The efficiency of using global variables for parameter passing is also higher than that of formal parameters.

⑥ For multi-byte variables (such as int type, float type variables, etc.), PICC follows the Little Endian standard, that is, the low byte is placed at the low address of the storage space, and the high byte is placed at the high address. Please pay attention when programming.

7 Conclusion

Generally, the codes generated by C language are relatively cumbersome, so to write high-quality and practical C language programs, you must have a detailed understanding of the microcontroller architecture and hardware resources. Using C language to develop PIC series microcontroller system software has the advantages of high code writing efficiency, intuitive software debugging, convenient maintenance and upgrading, high code reuse rate, and convenient cross-platform code transplantation. Therefore, the application of C language programming in microcontroller system design will become more and more extensive.

Keywords:PICC  PIC  compiler  program Reference address:PIC Programming Based on PICC Compilation Environment

Previous article:Adjustable countdown reminder made with PIC16F627
Next article:Design of hands-free passive keyless access control based on PIC16F639

Recommended ReadingLatest update time:2024-11-16 19:57

51. Comparison of AVR, PIC, MSP430, STM32 microcontrollers
51. Comparison of AVR, PIC, MSP430, STM32: common models, features, advantages and disadvantages, compilation software, download software, and download methods.          Traditional 8051: suitable for beginners, easy to use, average price (in terms of cost performance).   Disadvantages: easy to decrypt (traditional 51
[Microcontroller]
Convert BIN code of PIC microcontroller to BCD code
;******************************************************************** ;                  Binary To BCD Conversion RouTIne ;      This rouTIne converts a 16 Bit binary Number to a 5 Digit ; BCD Number. This rouTIne is useful since PIC16C55 & PIC16C57 ; have  two 8 bit ports and one 4 bit port ( total of 5 BCD digits)
[Microcontroller]
Design of wireless data transmission system based on nRF24L01 and PIC16F877
introduction In industrial control sites, it is often necessary to collect a large amount of field data, such as temperature, humidity, air pressure, etc., and transmit these data to the host for processing. The host transmits the control signal to the field execution module for various operations based on th
[Industrial Control]
Design of wireless data transmission system based on nRF24L01 and PIC16F877
Microchip Technology PIC32CZ CA MCUs Now Available at Mouser for Industrial and Automotive Security
May 7, 2024 – Mouser Electronics, an authorized global semiconductor and electronic component distributor focused on introducing new products, is now stocking Microchip Technology's PIC32CZ CA MCU. The PIC32CZ CA is a 32-bit high-performance MCU with multiple connectivity options, making it ideal for industr
[Microcontroller]
Microchip Technology PIC32CZ CA MCUs Now Available at Mouser for Industrial and Automotive Security
Using PIC MCU HT1621 LCD display controller principle
The HT1621 LCD display controller is a display component of a multifunctional fully automatic intelligent switch, which can monitor the operation of the power supply line in real time, accurately and online. Once the line has leakage, overload, short circuit, overvoltage, undervoltage and phase loss, the intelligent
[Microcontroller]
Using PIC MCU HT1621 LCD display controller principle
How to write PIC microcontroller configuration bits (MPLAB X Integrated Development Environment, XC Compiler)
I have recently come into contact with the MPLABX integrated development environment, X16 and X8 compilers, which are very different from the previous PIC development environment. Here I will talk about the first step of creating a new project, the writing of configuration bits. 1: The configuration bit writing exampl
[Microcontroller]
How to write PIC microcontroller configuration bits (MPLAB X Integrated Development Environment, XC Compiler)
How to use IIC communication inside PIC microcontroller correctly
#include #define uchar unsigned char #define uint unsigned int #define add 0xaa __CONFIG(0x3B31); const fly ee_data[]={1,2,3,4,5,6}; uchar read_data[6]; const uchar table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; void delay(uint x); void init(); void didi(volatile num); v
[Microcontroller]
How to use IIC communication inside PIC microcontroller correctly
Dynamic display of LEDs using PIC16F877A microcontroller
list p=16F877A,R=DEC include "p16F877A.inc" ;;;;;user variables;;;;;;;; Count2 equ 23H Count3 equ 24H data_out1 equ 25H data_out2 equ 26H ;;;;;;;reset vector;;;;;;;;; org 0x00 goto mainline ;;;;;;delay program;;;;;;; delay_2ms movlw 0x05 movwf Count2 lp0 movlw 0xff movwf
[Microcontroller]
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号