Sign in Join
Wiki copytemporary

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:

Bit Name Description
15 A/B: DACA or DACB Selection bit 0 = Write to DACA · 1 = Write to DACB
14 BUF: Vref Input Buffer Controlbit 0 = Unbuffered · 1 = Buffered
13 **GA:**Output Gain Selection bit 0 = 2x (VOUT = 2 * VREF * D / 4096) · 1 = 1x (VOUT = VREF * D / 4096)
12 SHDN: Output Shutdown Control bit 0 = Shutdown the selected DAC channel. Analog output is not available at the channel that was shut down. VOUT pin is connected to 500 kOhm(typical) · 1 = Active mode operation. VOUT is available.
11:0 D11:D0: DAC Input Data bits. Bit x is ignored.

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 3, last changed by WikiArchive .

Edited on wiki.freepascal.org by 1 person, 2020

From the official wiki's backup of 26 May 2024: who edited this page there, and when. Edits made there after that date were not recorded, and the earlier versions are not shown here; the main page says why.

WhenWhoWhat changed
TrevEnglish translation of German page

Talk about this page

Nobody has opened a bench for this page yet. Sign in to open one.