2017년 7월 5일 수요일

ISIS COMPONENT CREATING - PROTEUS


The video shows the creation of a component (FT232HL). The component is created for the creation of PCBs, not for simulations.



RING BUFFER UART - ATmega328p
PART 1

PART 2



Link: EXAMPLE

The DS3231 is a serial RTC with very high accuracy thanks to its internal 32KHz oscillator that is compensated for by temperature changes (TCXO or Temperature Compensated Crystal Oscillators). The data sheet tells us that we can have an accuracy of ± 2ppm that we can translate into about 126 sec per year.
The reading and writing of records of the DS3231 is done by the I2C interface at a speed of 400KHz.
The example presented in this post is for an ATmega32, but can be easily adapted to other microcontrollers.
In this previous post (I2C with ATmega8) explains the operation of the I2C bus, here I will only show and explain the I2C and RTC libraries necessary for writing and reading the DS3231.
I2C ATmega

The ATmega32 has 4 registers which are shown in figure 1 and that we must know. They configure the bus speed, control the bus, access the bus states and read / write the received / sent data.
Figure 1

PART 1. Files I2C

File i2c.h. Contains the definitions needed to configure the I2C bus.

⦁ In figure 2 the possible values of the TWBR register are calculated based on the I2C bus speed (400KHz).


Figure 2.

⦁ In Figure 3, the correct value of the TWBR register and the pre-scaling bits (TWPSX) is selected.


Figure 3.

⦁ Figure 4 shows the prototypes of the functions necessary for the management of the bus.
Figure 4. 

File i2c.c Contains the implementation of the functions declared in the header file .h.

⦁ In I2C_Init the bus speed I2C is configured.

Figure 5.


⦁ I2C_Start sends a start condition and waits for the shipment to take place. Returns 1 if the shipment was successful.
⦁ I2C_ReStart sends a new start condition and waits for the shipment to take place. Returns 1 if the shipment was successful.


Figure 6.


⦁ I2C_Stop sends a stop condition and waits for it to be executed.

Figure 7.


⦁ I2C_Write sends the data to the slave and returns a 1 if the send was made and an ACK was received.

Figure 8.

⦁ I2C_Read expects the bus to be enabled to start a read and send an ACK or NACK according to the value of the variable ACK_NACK.

Figure 9.



PART 2. Files RTC

Before starting with the files rtc.h and rtc.c I will briefly explain what are the structures and the joints.


⦁ A structure is a grouping of variables under a common name. These groupings may contain different types of data. To define a structure, use the reserved word "struct".
The example structure contains 3 members of different type (uint8_t, int16_t and an int8_t array).
The structure variable declaration is as follows:
Struct example var1: Here "var1" is a variable of the example structure type.
Example struct
{
     Uint8_t c;
     Int16_t i;
     Int8_t k [4];
};
To access the members of the structure, the dot (.) Operator is used.
Var1.c; Var. I; Var1.k [0], var1.k [1], var1.k [2] and var1.k [3].
Something simpler when creating structures is the declaration of an alias using the word cable "typedef". This will avoid putting "struct example" every time you want to declare a new variable.
Simply put "example var2".
Typedef struct
{
     Uint8_t c;
     Int16_t i;
     Int8_t k [4];
}example;
Structures can also be pointers and pointed by pointers as well as native types (char, int, etc). In these cases, members are accessed by the date operator (- & gt;).
Variable: example var1.puntero: example * pt = & amp; var1;
Use: pt- & amp; gt; c; Pt- & gt; i; Pt- & gt; k [0], pt- & gt; k [1], pt- & gt; k [2] and pt- & gt; k [3].

⦁ A union is similar to a structure, but these differ in that each element in the structures has a space of memory while in the unions all the elements occupy the same space of memory. The size of the union depends on the largest member.
The union shown on the right side occupies only 4 bytes.
After the assignment the values are distributed as in the following figure where the most significant byte is the latter since ATmel uses little endian.



The user will see the variables as in the following figure.


Creation:
          Typedef union
          {
               Uint8_t u8;
               Uint16_t u16;
               Uint32_t u32;
          }example;

Declaration:
             Example var1;

Assignment:

            Var1.u32 = 0x01234567

Now we will move to rtc files.

File rtc.h


⦁ In Figure 10 the structures for time and date are created. There is also a third structure (RTC_t) that is conformed by the structures Hora_t and Date_t.

Figure 10.



⦁ In Figure 11 the addresses of the DS3231 internal registers are defined. Also a mask to filter the data read from the DS3231. Finally, since the address of the DS3231 is 0b1101000, DS3231_READ and DS3231_WRITE are defined for readings and writes to and from the RTC.


Figure 11.

⦁ Figure 12 shows the prototype functions for reading / writing the RTC. The last 6 functions have a structure pointer (Time_t, Date_t, and RTC_t).

Figure 12.

File rtc.c

⦁ RTC_Init only initializes the I2C bus.


Figure 13.

⦁ Figure 14 shows the read / write functions for any DS3231 record.

Figure 14.

⦁ RTC_SetHora writes a new time to the DS3231. The new time comes from a structure of type Time_t. Similarly RTC_SetDate writes a new date on the DS3231.

Figura 15.


⦁ RTC_GetTime read the DS3231 time and save it to a structure of type Time_t that is pointed to by the hour pointer. RTC_GetFake does a similar task with the date.

Figure 16.


⦁ RTC_GetTime uses the aforementioned functions to read the time and date and save it in the structure pointed to by the rtcde pointer type RTC_t. RTC_SetTime handles the time and date in a similar way.
Figura 17.

PART 3. main

In the main the uart is configured to send / receive the time and date to / from a program made in Visual C #.

An interrupt is also set every 1 second to read the DS3231.

Figure18.

Here I present the program.

⦁ Figure 19 shows the includes that the main needs.

Figure 19.

⦁ Figure 20 shows the definition of the union TRAMA_t that joins a structure and an array of 10 elements. This new type of data (TRAMA_t) will serve to send and receive information to and from the program on the PC. In line 28, the variable "tx_frame" is created.
⦁ In line 27, two variables (rtc and rx_rtc) of type RTC_t are declared. The rtc variable stores the read time and date of the DS3231 every 1 second. Rx_rtc is used to store the time and date received from the program on the PC before being sent to the DS3231.
⦁ The variables update_rtc and send_rtc are updated in the interrupt of uart and serve to update the DS3231 or send the time and date to the PC.
Figure 20.

⦁ In the lines 37-40 (Figure 21) the uart is configured.
⦁ Lines 42-44 set the timer1 interrupt every 1 second.
⦁ Lines 48 and 49 initialize the variables update_rtc and send_rtc.
⦁ The variable tx_path is also initialized and the global interrupt bit is activated.
Figure 21.

⦁ If the PC program sends a new update for the RTC it will be stored in rx_rtc (in the interrupt by reception) and the RTC will be updated in the while. The current time and date will also be sent to the PC if required.
Figure 22.

⦁ Figure 23 shows the reception interrupt of the uart. Here all data is received, a data integrity check is performed and the variables 'update_rtc' and 'send rtc' are updated according to the read command ('R') or write ('W').

Figure 23.


⦁ Finally, in the interruption of the timer1 the time and date of the rtc is read. It also shows the functions of reading and writing in the uart.
Figure 24.


Program Links:

RTC Program DS3231
HORA+FECHA.exe



First project with Atmel Studio 7

To start uC AVR programming we need to install ATmel's Integrated Development Platform (IDP), I mean Atmel Studio 7.

Here the link for the download: Atmel Studio 7.0.790

Once the software is installed, we will begin to create our first project.

Once the software is open, on the left side we will see Figure 1 where we must click on "New Project".
Once the language is selected, we must name the project, in our case we will call it "First_project" (Figure 3). The software will create a folder with the project name in the path "C: \ Users \ user \ Documents \ Atmel Studio".
Figure 3.
image

Now we must select the device that we want to use, in this case we select the ATmega32.
Figure 4.


To the right of the same window we will see (figure 4) we will see a list of the debugging and programming tools that can be used in the selected microcontroller. Also a link to the data sheet of the device (Figure 5).
Figure 5.


After clicking on the accept button we will see the file main.c as in figure 6. This is where we should write our program.

Figure 6.


The developed application is shown in figure 7. In this program there will be two inputs for two pushbuttons on port B, and two outputs for two LEDs on port D.

⦁ In 11, two variables of type unsigned char (uint8_t) are declared to save in the current state and the last state of an input pin.
⦁ In 15 the port B are entered as inputs.
⦁ In 16 we activate the pull up resistors of the PB0 and PB1 pins.
⦁ In 17 the pins PD7 and PD3 are set as outputs for the LEDs.
⦁ At 20 we asked if the PB0 pin was pressed
⦁ In 21 the pin PD7 will be set to 1 if PB0 is 0. The code in line 22 is the same as in line 21.
⦁ At 24 the pin PD7 will be set to 0 if PB0 is 1. The code in line 25 is the same as in line 24.
⦁ The previous value of pin PB1 is stored at 27.
⦁ The current value of pin PB1 is saved at 28.
⦁ At 29 you wonder if a rising flank occurred.
⦁ At 31, the pin PD3 is switched using an xor (^). The code for line 32 is the same as for line 31.

Figure 7.


In C we can use the operator:?, And thanks to this we can reduce the lines 20 to 25 by the code of figure 8.

Figure 8.image


Figure 9 shows the equivalence between an if-else and the operator:?.
Figure 9.

Then we must compile the program using the button in figure 10.

Figure 10.image

Finally, we will output the .hex file (Figure 11) in order to program our microcontroller.
Figure 11.




If we want to see the numbering of lines in our editing window we have to go to Tools> Options (Figure 12).

Figure 12.


Then in "All Languages" select "Line numbers" (Figure 13).

Figure 13.


I hope this post is helpful.

Until next time.

USBasp Bootloader

Already many know the USBasp programmer (thanks to Thomas Fischl) and how well this works. The USBasp should be one of the best known programmers to download code to an ATmega, this thanks to using a very economical ATmega8, which even without having USB port, is able to work with a lot of devices. ... and best of all: "It's free".

Personally I've been using it since 2010. Now I have an AVRISPmk2 (apparently already discontinued) and a JTAGICE3 (which was already replaced by the Atmel-ICE) and still sometimes use my USBasp.

Well, this post will show you how to use the "USBasp" as bootloader.
A USBasp programmer basically consists of an ATmega8 that has been programmed, in the application section of its flash, with a code that allows USB (low speed 1.5Mbps) communication with the programmer and programming other uCs. The above described is shown in figure 1, where the boot section of the uC (ATmega8) is not used.
Figure 1.

But when we talk about using "USBasp" as bootloader we will have a scheme similar to figure 2. Here, the code, "USBasp", that will communicate with the program on the PC (eg AVRDUDE) is located in the section Flash boot, and it is this code that allows us to put our application in the application section of the flash (using SPM and LPM instructions).

That is to say that we will not need a USBasp programmer since this one will have it integrated in the same uC. Best of all is that we can put a different uCs and with different oscillators. Personally I have already tested it with ATmega8 (at 12 and 16MHz), ATmega32 (at 12 and 16MHz) and ATmega324P (at 12.16 and 20 MHz).
  
Figure 2.


The necessary hardware is shown in figure 3. Here you should have some considerations such as.

⦁ D + must necessarily be connected to pin INT0.
⦁ D- can be any pin in port D.

⦁ The jumper to start the bootloader can be any pin.


Figure 3.

Figure 4 shows the bootloader flow diagram.
After a reset is started in bootloader and this will be executed yes:

⦁ The reset source is external (MCUCSR & (1 << EXTRF)).
⦁ If the jumper is set ((PINB & (1 << JUMPER_BIT)) == 0).

In other words, to execute the bootloader you have to place the jumper and press the reset button.

To exit the bootloader just remove the jumper.
  
    Figure 4.

    Before programming the bootoalder we must modify the following fuses.

    ⦁ In High Fuse we must select one of the sections that are at least 1024 words (2048 bytes) since the bootloader occupies more than 1900 bytes. We must also select "Boot Reset Enable" so that the program starts in the boot section and not in the application section. For ATmega8 I recommend 0xC8.

    ⦁ In Low Fuses we must select one of the options Ext. Crystal / Resonator High Freq. For an ATmega8 I recommend 0xFF.


    Figura 5.


    Figure 6 shows the memory map of the boot section of an ATmega8. As we said before, we will use more than 1900 bytes, so in the fuses will select the largest area.

    Figure 6.

    SOFTWARE

    The original code can be found at the following link

    Here I leave the project in ATMEL STUDIO 7 USBasp-bootThe project is configured for an ATmega8 at 12MHz, but can be easily changed to other devices.
    The modifications necessary to use it with other devices are the following:

    ⦁ If you want to use other oscillator frequencies we must make the change in Toolchain> Symbols. Frequencies can be 12,15,16,18 and 20 MHz. Figures 7 and 8 show the locations where frequency changes are to be made.

    Figure 7.

    Figure 8.


    We should also tell the compiler that the generated code should start in the boot section selected in the High Fuses. In the example in Figure 5, "Boot start address = 0x0C00" is selected where 0xC00 is the start address of the booting section.
    We have two ways to reassign the code:
    In Figure 9 the reallocation is done using the start of the address in words (0x0C00).
    In Figure 10, the reallocation is done using the address start in bytes (0x1800).
    We must select only one of the two forms (Figure 9 or 10).
    Note that 0x0C00 words = 0x1800 bytes.

    Figure 9.

    Figure 10.


    Figure 11 shows part of the generated code. Here we see that the start is in the address 0x1080 (for 2014 bytes). When the generated code is for the application section the start address is 0x0000. 


    Figure 11.
    Figure 12 indicates that PD3 will be used to connect USB D-. This can be changed to some other pin on the same port.
      
    Figure 12.

    Figure 13 shows the pin to be used for the bootloader boot jumper. This can be any pin that is not being used.
      

    Figure 13.

    In Figure 14, the pull-up resistor corresponding to the jumper pin is activated.
      

    Figure 14.

    Figure 15 evaluates the condition for remaining or leaving the booting area.
      Figure 15.


    In the case of figure 14 and 15 you can use the pin and the port that you wanted.
    If the ATmega that we want to use was not in the list of figure 16 corresponds to add it with their respective "SIGNATURE BYTES".


      Figure 16.


    El proyecto es para un ATmega8, cómo cambiamos de dispositivo ?

    ⦁ We click on the icon      
    ⦁ Click on "Change Device ..."  

    ⦁ Select the new device.
    ⦁ We will have changed our new device. 
    ⦁ Then there is only compiling and we will have the .hex of the bootloader to be able to program it.

    Finally, when the bootloader is installed, we can use programs like SinaProg to download our application without affecting the bootloader.
    It is necessary to emphasize that the bootloader does not allow to make change of the fuses.

    In summary:

    1. Prepare the hardware (figure 3).
    2. With any programmer change the fuses of the uC (figure 5).
    3. Make changes to the software only if required: F_CPU (figures 7 and 8), .text (figure 9 or 10), D- (figure 12), JUMPER_BIT (figure 13), PORT / PIN JUMPER 14 and 15).
    4. Add a new uC if missing (Figure 16).

    I hope this is useful, since not needing a programmer can be very useful.