Wiki copymirror

This is a mirror of the wiki at pascal.chat. Editing, history and sign-in are there.

AVR Embedded Tutorial - SPI MCP4922

Deutsch · English

Control an MCP4922 12 bit DAC via SPI

This code is for an Atmega328 / Arduino with a 16MHz clock and an SPI compatible MCP4922 Digital/Analog Converter (DAC).

The following functions are described in other tutorials:

This example shows how to control the MCP4922 DAC via SPI.

Functions for the 74HC595 shift register

Constants

Pins which are required at PORTB for SPI.

pascal
 type
   TSPIGPIO = bitpacked record
     p0, p1, SlaveSelect, MOSI, MISO, Clock, p6, p7 : boolean;
   end;

 var
   SPI_PORT : TSPIGPIO absolute PORTB;
   SPI_DDR  : TSPIGPIO absolute DDRB;

Initialize SPI

pascal
 procedure SPIInit;
 begin
   // Setup SPI port for output
   SPI_DDR.MOSI        := True;
   SPI_DDR.Clock       := True;
   SPI_DDR.SlaveSelect := True;

   SPCR := (1 shl SPE) or (0 shl SPIE) or (0 shl DORD) or (1 shl MSTR) or (0 shl CPOL) or (0 shl CPHA) or (%01 shl SPR);
   SPSR := 1 shl SPI2X;  // SCK x 2 on 1 MHz
 end;

Write SPI

pascal
 procedure SPIWrite(p : PByte; len : byte);
 var
   i : byte;
 begin
   SPI_Port.SlaveSelect := False;

   for i := len - 1 downto 0 do
     begin
       SPDR := p[i];
       
       while(SPSR and (1 shl SPIF)) = 0 do
         begin
         end;
   end;

   SPI_Port.SlaveSelect := True;
 end;

MCP4922 functions

Bit assignments for the MCP4922:

<thead>

</thead> <tbody>

<strong>1</strong> = Write to DACB</td>

<strong>1</strong> = Buffered</td>

<strong>1</strong> = 1x (VOUT = VREF * D / 4096)</td>

<strong>1</strong> = Active mode operation. VOUT is available.</td>

</tbody>

Send to DAC

pascal
 procedure MCP4922sendValue(Value : UInt16; Channel : Byte);
 type
   TADC = bitpacked record
     Value : 0..4095;  // bits 0-11
     ShutDown,         // bit 12
     Gain,             // bit 13
     VRef,             // bit 14
     DAC : 0..1;       // bit 15
   end;

 begin
   with TADC(Value) do 
     begin
       ShutDown := 1;
       Gain     := 1;
       VRef     := 0;
       Dac      := Channel;
   end;

   SPIWrite(@Value, 2);
 end;

Example program

This example shows the output of two analog values ​​from the DAC. Two LEDs connected to the DAC flash alternately with a very smooth transition.

Constants and variables

A counting variable that counts up to 4095.

pascal
 var
   z : Int16 ;

Main program

Alternately write a value in DAC 0 & 1.

pascal
 begin
   // initialize SPI.
   SPIInit; 

   repeat
     for z := 0 to 4095 do 
       begin
         MCP4922sendValue(4095 - z, 0);
         MCP4922sendValue(z, 1);
       end;
   until 1 = 2;
 end.

See also


From the Free Pascal wiki, page "AVR Embedded Tutorial - SPI MCP4922", as it stood on 2020-03-08 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.

Revision 2, last changed by WikiArchive .